From f474a5dc5bfd41711a6e6812d5d5698313bd1d48 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 29 Sep 2023 11:00:13 +0200 Subject: [PATCH] Set the `TARGET` env variable when running rustc The goal is to be able to do things differently in a proc macro depending on the target platform. It is already defined for build script and it would help to have it for macros as well. Closes: #10714 --- src/cargo/core/compiler/compilation.rs | 11 ++++++++--- src/doc/src/reference/environment-variables.md | 3 +++ tests/testsuite/build_script.rs | 1 + tests/testsuite/cross_compile.rs | 10 +++++++--- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/cargo/core/compiler/compilation.rs b/src/cargo/core/compiler/compilation.rs index e03a08d3947..9fbcfcac2a9 100644 --- a/src/cargo/core/compiler/compilation.rs +++ b/src/cargo/core/compiler/compilation.rs @@ -183,7 +183,7 @@ impl<'cfg> Compilation<'cfg> { self.rustc_process.clone() }; - let cmd = fill_rustc_tool_env(rustc, unit); + let cmd = fill_rustc_tool_env(rustc, unit, &self.host); self.fill_env(cmd, &unit.pkg, None, unit.kind, true) } @@ -194,7 +194,7 @@ impl<'cfg> Compilation<'cfg> { script_meta: Option, ) -> CargoResult { let rustdoc = ProcessBuilder::new(&*self.config.rustdoc()?); - let cmd = fill_rustc_tool_env(rustdoc, unit); + let cmd = fill_rustc_tool_env(rustdoc, unit, &self.host); let mut cmd = self.fill_env(cmd, &unit.pkg, script_meta, unit.kind, true)?; cmd.retry_with_argfile(true); unit.target.edition().cmd_edition_arg(&mut cmd); @@ -373,7 +373,7 @@ impl<'cfg> Compilation<'cfg> { /// Prepares a rustc_tool process with additional environment variables /// that are only relevant in a context that has a unit -fn fill_rustc_tool_env(mut cmd: ProcessBuilder, unit: &Unit) -> ProcessBuilder { +fn fill_rustc_tool_env(mut cmd: ProcessBuilder, unit: &Unit, host_triple: &str) -> ProcessBuilder { if unit.target.is_executable() { let name = unit .target @@ -383,6 +383,11 @@ fn fill_rustc_tool_env(mut cmd: ProcessBuilder, unit: &Unit) -> ProcessBuilder { cmd.env("CARGO_BIN_NAME", name); } cmd.env("CARGO_CRATE_NAME", unit.target.crate_name()); + let target_triple = match &unit.kind { + CompileKind::Host => host_triple, + CompileKind::Target(t) => t.short_name(), + }; + cmd.env("TARGET", target_triple); cmd } diff --git a/src/doc/src/reference/environment-variables.md b/src/doc/src/reference/environment-variables.md index 37c788f8dec..65fc65f7b26 100644 --- a/src/doc/src/reference/environment-variables.md +++ b/src/doc/src/reference/environment-variables.md @@ -247,6 +247,9 @@ corresponding environment variable is set to the empty string, `""`. * `OUT_DIR` --- If the package has a build script, this is set to the folder where the build script should place its output. See below for more information. (Only set during compilation.) +* `TARGET` --- the target triple that is being compiled for. Native code should be + compiled for this triple. See the [Target Triple] description + for more information. (Only set during compilation.) * `CARGO_BIN_EXE_` --- The absolute path to a binary target's executable. This is only set when building an [integration test] or benchmark. This may be used with the [`env` macro] to find the executable to run for testing diff --git a/tests/testsuite/build_script.rs b/tests/testsuite/build_script.rs index 0ccbb4e27d7..66057b8ee65 100644 --- a/tests/testsuite/build_script.rs +++ b/tests/testsuite/build_script.rs @@ -5101,6 +5101,7 @@ fn duplicate_script_with_extra_env() { compile_error!{"expected mycfg set"} // Compile-time assertion. assert_eq!(env!("CRATE_TARGET"), "{target}"); + assert_eq!(env!("TARGET"), "{target}"); // Run-time assertion. assert_eq!(std::env::var("CRATE_TARGET").unwrap(), "{target}"); } diff --git a/tests/testsuite/cross_compile.rs b/tests/testsuite/cross_compile.rs index 1bc0c277db1..bf031844a39 100644 --- a/tests/testsuite/cross_compile.rs +++ b/tests/testsuite/cross_compile.rs @@ -30,7 +30,7 @@ fn simple_cross() { assert_eq!(std::env::var("TARGET").unwrap(), "{}"); }} "#, - cross_compile::alternate() + cross_compile::alternate(), ), ) .file( @@ -40,9 +40,11 @@ fn simple_cross() { use std::env; fn main() {{ assert_eq!(env::consts::ARCH, "{}"); + assert_eq!(env!("TARGET"), "{}"); }} "#, - cross_compile::alternate_arch() + cross_compile::alternate_arch(), + cross_compile::alternate() ), ) .build(); @@ -101,9 +103,11 @@ fn simple_cross_config() { use std::env; fn main() {{ assert_eq!(env::consts::ARCH, "{}"); + assert_eq!(env!("TARGET"), "{}"); }} "#, - cross_compile::alternate_arch() + cross_compile::alternate_arch(), + cross_compile::alternate() ), ) .build();