How can I find the current Rust compiler's default LLVM target triple?

Viewed 5400

I want to override a build script, which means adding a configuration section that looks like this:

[target.x86_64-unknown-linux-gnu.foo]
rustc-link-search = ["/path/to/foo"]
rustc-link-lib = ["foo"]
root = "/path/to/foo"
key = "value"

But I'm using a Mac, so x86_64-unknown-linux-gnu isn't the correct target triple.

How do I discover which target triple rustc or cargo are currently using?

rustc --print cfg prints a list of values that don't seem to correspond to the triple (there's no unknown in there, in particular).

rustc --print target-list displays all available targets; I just want the default.

7 Answers

cargo uses rustc -vV to detect the default target triple (source). We can do the same thing:

use std::process::Command;

use anyhow::{format_err, Context, Result};
use std::str;

fn get_target() -> Result<String> {
    let output = Command::new("rustc")
        .arg("-vV")
        .output()
        .context("Failed to run rustc to get the host target")?;
    let output = str::from_utf8(&output.stdout).context("`rustc -vV` didn't return utf8 output")?;

    let field = "host: ";
    let host = output
        .lines()
        .find(|l| l.starts_with(field))
        .map(|l| &l[field.len()..])
        .ok_or_else(|| {
            format_err!(
                "`rustc -vV` didn't have a line for `{}`, got:\n{}",
                field.trim(),
                output
            )
        })?
        .to_string();
    Ok(host)
}

fn main() -> Result<()> {
    let host = get_target()?;
    println!("target triple: {}", host);
    Ok(())
}

Based on @konstin answer:

$ rustc -vV | sed -n 's|host: ||p'

which gives you something like:

x86_64-unknown-linux-gnu

What worked for me (inspired by rodrigo's answer)

RUSTC_BOOTSTRAP=1 rustc -Z unstable-options --print target-spec-json | python3 -c 'import json,sys;obj=json.load(sys.stdin);print(obj["llvm-target"])'

RUSTC_BOOTSTRAP=1 bypasses the check that normally allows certain features to only be used on the nightly branch. I also used a proper json parser rather than grep.

It's not particularly elegant perhaps, but I found this to work:

rustup show | grep default | grep -Po "^[^-]+-\K\S+"

I write a lot of cross-platform shell scripts or Python programs that need to check my current Rust default target triple. I don't like manually grepping the string value, though.

To make it easier to get the default target triple, I packaged konstin's answer into a command line tool.

You can install it with:

cargo install default-target

and then you can use the program just by running:

default-target

and it'll return your current target triple. Something like x86_64-apple-darwin or x86_64-unknown-linux-gnu.

You can find more details about the crate on crates.io, docs.rs, and GitHub.

With a recent enough rustc compiler:

$ rustc -Z unstable-options --print target-spec-json | grep llvm-target

You can use the current_platform crate:

use current_platform::CURRENT_PLATFORM;

fn main() {
    println!("Running on {}", CURRENT_PLATFORM);
}

This will print Running on x86_64-unknown-linux-gnu on desktop Linux.

Unlike all the other answers, this is zero cost: the platform is determined at compile time, so there is no runtime overhead. By contrast, calls to rustc are expensive: if Rust is installed through rustup.rs, any rustc command takes ~100ms.

Related