How can I query rustc for the host triple?

2.3k Views Asked by At

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.

4

There are 4 best solutions below

3
On BEST ANSWER
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.

3
On

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.

1
On

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!

0
On

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);
}