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.

Tenders McChiken
  • 1,216
  • 13
  • 21
  • 2
    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 `rustc` – Alexey S. Larionov Sep 01 '20 at 10:20
  • 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. – Tenders McChiken Sep 01 '20 at 10:26
  • You can take `gcc`'s triplet output via bash and substitute it in a build command – Alexey S. Larionov Sep 01 '20 at 10:30

4 Answers4

7
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

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.

Danilo Bargen
  • 18,626
  • 15
  • 91
  • 127
  • 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](https://github.com/rust-lang/rust/issues/71009), it gets stabilized. I'll leave this question open and accept your answer once the flag is stabilized. – Tenders McChiken Sep 01 '20 at 12:57
  • 1
    `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? – Max Aug 01 '21 at 17:25
  • @Max 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. – Betamos Mar 02 '22 at 12:48
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!

Tenders McChiken
  • 1,216
  • 13
  • 21
  • 2
    Note that you can get the directory with `rustc --print sysroot`, so `basename $(rustc --print sysroot)` will give you the triple – Jmb Sep 01 '20 at 12:46
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);
}
Dmitrii Demenev
  • 735
  • 1
  • 5
  • 13