How can I query rustc for the host triple?
Asked Answered
C

4

10

When working with gcc, I can get what gcc thinks is my host's triplet by running gcc -dumpmachine. On my current system, this gives me x86_64-linux-gnu.

How can I get stable rustc to print my host triple? (x86_64-unknown-linux-gnu in this case)

rustc's documentation doesn't seem to contain anything relevant besides the --print and --version. Neither seem to produce the host target triple.

Clarification: with two answers being given about nightly so far, I want to stress that this question is specifically about stable rustc compilers.

Clingfish answered 1/9, 2020 at 10:17 Comment(3)
GCC is pretty much originator of triplets notation, so just refer to it. Rust is just using the same notation to reduce confusion, though I agree it would be cool to have this feature in rustcIxtle
So there isn't a way to get the host triple from rustc? I'm trying to avoid maintaining a handwritten mapping of triples if I can avoid it.Clingfish
You can take gcc's triplet output via bash and substitute it in a build commandIxtle
S
9
rustc --version --verbose

Will give you some output like:

rustc 1.35.0-nightly (474e7a648 2019-04-07)
binary: rustc
commit-hash: 474e7a6486758ea6fc761893b1a49cd9076fb0ab
commit-date: 2019-04-07
host: x86_64-unknown-linux-gnu
release: 1.35.0-nightly
LLVM version: 8.0

Where host is your target triple.

Same answered 13/9, 2020 at 1:36 Comment(3)
Hi Taylor, and welcome to SO. Unfortunately, rustc doesn't show the target triple on stable. It only shows the first line rustc 1.46.0 (04488afe3 2020-08-24).Clingfish
(Cross-posted from somewhere) If you have awk: rustc -vV | awk '/^host/ { print $2 }'Trescott
Looks like this works on stable now. Accepting answer.Clingfish
I
3

With Rust nightly, you can print the "target spec JSON":

$ rustc +nightly -Z unstable-options --print target-spec-json
{
  "arch": "x86_64",
  "cpu": "x86-64",
  "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
  "dynamic-linking": true,
  "env": "gnu",
  "executables": true,
  "has-elf-tls": true,
  "has-rpath": true,
  "is-builtin": true,
  "linker-flavor": "gcc",
  "linker-is-gnu": true,
  "llvm-target": "x86_64-unknown-linux-gnu",
  "max-atomic-width": 64,
  "os": "linux",
  "position-independent-executables": true,
  "pre-link-args": {
    "gcc": [
      "-Wl,--as-needed",
      "-Wl,-z,noexecstack",
      "-m64"
    ]
  },
  "relro-level": "full",
  "stack-probes": true,
  "target-c-int-width": "32",
  "target-endian": "little",
  "target-family": "unix",
  "target-pointer-width": "64",
  "vendor": "unknown"
}

To parse the target triple from this on the command line, you could use a tool like jq:

$ rustc +nightly -Z unstable-options --print target-spec-json | jq -r '."llvm-target"'
x86_64-unknown-linux-gnu

This isn't stable yet (and therefore requires the -Z unstable-options compiler option), but it probably will be in the future. The feature was added in #38061.

Implode answered 1/9, 2020 at 12:19 Comment(3)
Thanks. I decided to ask here because I saw target-spec-json was unstable. You're right that this anser will be the correct one when, or perhaps if, it gets stabilized. I'll leave this question open and accept your answer once the flag is stabilized.Clingfish
llvm-target can be different from what rustc considers the "host", and there's no guarantee that it's a valid target for rustc, right? In most cases it will be but not necessarily all?Deadpan
@Deadpan is correct, using llvm-target is not reliable. My rustc target triple is aarch64-apple-darwin but llvm-target is arm64-apple-macosx11.0.0. Taylor's answer works for me.Vikkivikky
C
1

rustc (as of version 1.45.2) doesn't seem to offer any way of getting the host target triple.

As a workaround, I decided to use strace and a small dummy program to trick the compiler into showing the host triple; rustc stores precompiled libraries in separate directories based on their platform triple.

This is what I ended up with:

strace -f -e trace=file rustc <(echo "fn main(){};") 2>&1 | \
   grep -E "(libstd-.*\.rlib)|(libcore-.*\.rlib)" | \
   sed -E  "s:^.*\"/.*/([^/]+-[^/]+(-[/^]+(-[^/]+)?)?)/.*\".*$:\1:g;t;d" | \
   sort | uniq

It works as you'd expect, producing x86_64-unknown-linux-gnu with a gnu ABI rust installation on a 64-bit Linux system.

In theory, this should work with any version of rustc. I can confirm it works with rustc 1.43.0 (shipped with Ubuntu 18.04) and 1.45.2.

Here are some caveats to be aware of when use this command:

  1. This command requires bash because I'm using the <(..) construct. This command can be amended to use explicit temporary files at the expense of more complexity.
  2. This command will produce more than one target triple if the compiler attempts to access files for platforms other than the host. This is deliberate. If this is a problem, you can take a heuristic-based approach by using uniq (with --count), sort, and head to pick the most accessed triple.
  3. The regex used to filter triples is not as rigid as I'd like. It can probably be narrowed down much further if triples adhere to a formal spec. I'll update later if I manage to find some time.

Cheers!

Clingfish answered 1/9, 2020 at 12:19 Comment(1)
Note that you can get the directory with rustc --print sysroot, so basename $(rustc --print sysroot) will give you the tripleParker
H
0

I've written a rustc_host crate that allows to do that!

Example:

extern crate rustc_host;

fn main() {
    let host_triple = rustc_host::from_cli()
        .expect("failed to get host triple from rustc");
    println!("host triple: {}", host_triple);
}
Hoarse answered 3/2, 2023 at 1:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.