How to get executable's full target triple as a compile-time constant without using a build script?
Asked Answered
S

4

13

I'm writing a Cargo helper command that needs to know the default target triple used by Rust/Cargo (which I presume is the same as host's target triple). Ideally it should be a compile-time constant.

There's ARCH constant, but it's not a full triple. For example, it doesn't distinguish between soft float and hard float ARM ABIs.

env!("TARGET") would be ideal, but it's set only for build scripts, and not the lib/bin targets. I could pass it on to the lib with build.rs and dynamic source code generation (writing the value to an .rs file in OUT_DIR), but it seems like a heavy hack just to get one string that the compiler has to know anyway.

Is there a more straightforward way to get the current target triple in lib/bin target built with Cargo?

Sociable answered 24/2, 2018 at 21:3 Comment(2)
The host is what platform is performing the compilation; the target is what platform the code will be executed on. You use these terms interchangeably; which do you need?Poseur
@Poseur I'm aware of the differences. Please note that I'm talking about building of a Cargo helper command, so the compilation target arch during helper's own compilation becomes the host arch once it's run.Sociable
N
7

Build scripts print some additional output to a file so you can not be sure that build script only printed output of $TARGET.

Instead, try something like this in build.rs:

fn main() {
    println!(
        "cargo:rustc-env=TARGET={}",
        std::env::var("TARGET").unwrap()
    );
}

This will fetch the value of the $TARGET environment variable in the build script and set it so it will be accessible when the program is started.

In my main.rs:

const TARGET: &str = env!("TARGET");

Now I can access the target triplet in my program. If you are using this technique, you'll only read the value of theTARGET environment variable and nothing else.

Narine answered 12/7, 2018 at 17:14 Comment(0)
T
2

I don't think this is exposed other than through a build script. A concise way to get the target triple without "dynamic source code generation" would be, in build.rs:

fn main() {
    print!("{}", std::env::var("TARGET").unwrap());
}

and in src/main.rs:

const TARGET: &str = include_str!(concat!(env!("OUT_DIR"), "/../output"));

fn main() {
    println!("target = {:?}", TARGET);
}
Tempe answered 25/2, 2018 at 6:31 Comment(2)
Thanks! I forgot include_str! exists. So that is marginally more straightforward than include!, but still uses OUT_DIR, so not as nice as I hoped.Sociable
Starting from Rust 1.19.0, you could supply the env var in build.rs as println!("cargo:rustc-env=TARGET={}", var("TARGET").unwrap()), and read it in main.rs as const TARGET: &str = env!("TARGET");.Flanna
A
1

If anyone else comes across this, Shnatsel made a crate that worked really well for me. Uses the same method as the accepted answer but doesn't muddy up your build.rs since it's a crate. Provides Target Triple and Compiled-on Host Triple.

Lots of downloads, so I must be the only person who had trouble finding it, so I'm adding it here for posterity (:

https://crates.io/crates/current_platform

Active answered 14/2 at 16:10 Comment(0)
A
0

If you just want to know which target is installed, run: rustup target list --installed

Aucoin answered 1/11, 2021 at 14:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.