From 4860994c6fd3e1320d2d8fc14d5de0bed44e5717 Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Mon, 10 Aug 2026 17:03:13 +0100 Subject: [PATCH 1/7] typo: Fix previously added typo --- src/compiler/build_context/target_info.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/compiler/build_context/target_info.rs b/src/compiler/build_context/target_info.rs index 150950311a9..a3576e5622b 100644 --- a/src/compiler/build_context/target_info.rs +++ b/src/compiler/build_context/target_info.rs @@ -168,8 +168,6 @@ impl TargetInfo { /// invocation is cached by [`Rustc::cached_output`]. /// /// Search `Tricky` to learn why querying `rustc` several times is needed. - /// - /// When a Workspace is provided, #[tracing::instrument(skip_all)] pub fn new( gctx: &GlobalContext, From 56f102fc20bb71972b8cd172d635b8b594aa3b10 Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Tue, 25 Aug 2026 14:59:44 +0100 Subject: [PATCH 2/7] test(rustc): Test that the sysroot lookup respects RUSTFLAGS --- src/util/rustc.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/util/rustc.rs b/src/util/rustc.rs index 1ab62ae0134..036f51710f1 100644 --- a/src/util/rustc.rs +++ b/src/util/rustc.rs @@ -407,3 +407,22 @@ fn process_fingerprint(cmd: &ProcessBuilder, extra_fingerprint: u64) -> u64 { env.hash(&mut hasher); Hasher::finish(&hasher) } + +#[cfg(test)] +mod tests { + use crate::GlobalContext; + use crate::util::data_structures::HashMap; + use std::path::Path; + + #[test] + fn sysroot_fetch_respects_env_rustflags() { + let mut gctx = GlobalContext::default().unwrap(); + + let rustflags = HashMap::from_iter([("RUSTFLAGS".to_string(), "--sysroot=.".to_string())]); + gctx.set_env(rustflags); + + let rustc = gctx.load_global_rustc(None).unwrap(); + let sysroot = rustc.sysroot(&gctx).unwrap(); + assert_ne!(sysroot, Path::new(".")); + } +} From e5a08b67fd684eec64ac3de9ed4bff2f5ddcf17e Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Tue, 25 Aug 2026 13:47:23 +0100 Subject: [PATCH 3/7] refactor(rustc): Move RUSTFLAGS helper function from target_info.rs to util/rustc.rs --- src/compiler/build_context/target_info.rs | 23 ++----------------- src/util/rustc.rs | 28 +++++++++++++++++++++++ 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/compiler/build_context/target_info.rs b/src/compiler/build_context/target_info.rs index a3576e5622b..3955e319240 100644 --- a/src/compiler/build_context/target_info.rs +++ b/src/compiler/build_context/target_info.rs @@ -14,6 +14,7 @@ use crate::compiler::CrateType; use crate::compiler::apply_env_config; use crate::context::{GlobalContext, StringList, TargetConfig}; use crate::util::interning::InternedString; +use crate::util::rustc::get_rustflags_from_env; use crate::util::{CargoResult, Rustc}; use crate::workspace::{Dependency, Package, Target, TargetKind, Workspace}; @@ -823,27 +824,7 @@ fn extra_args( /// Gets compiler flags from environment variables. /// See [`extra_args`] for more. fn rustflags_from_env(gctx: &GlobalContext, flags: Flags) -> Option> { - // First try CARGO_ENCODED_RUSTFLAGS from the environment. - // Prefer this over RUSTFLAGS since it's less prone to encoding errors. - if let Ok(a) = gctx.get_env(format!("CARGO_ENCODED_{}", flags.as_env())) { - if a.is_empty() { - return Some(Vec::new()); - } - return Some(a.split('\x1f').map(str::to_string).collect()); - } - - // Then try RUSTFLAGS from the environment - if let Ok(a) = gctx.get_env(flags.as_env()) { - let args = a - .split(' ') - .map(str::trim) - .filter(|s| !s.is_empty()) - .map(str::to_string); - return Some(args.collect()); - } - - // No rustflags to be collected from the environment - None + get_rustflags_from_env(gctx, flags.as_env()) } /// Gets compiler flags from `[target]` section in the config. diff --git a/src/util/rustc.rs b/src/util/rustc.rs index 036f51710f1..da8f92aaf1c 100644 --- a/src/util/rustc.rs +++ b/src/util/rustc.rs @@ -408,6 +408,34 @@ fn process_fingerprint(cmd: &ProcessBuilder, extra_fingerprint: u64) -> u64 { Hasher::finish(&hasher) } +/// Gets compiler flags from environment variables. +pub(crate) fn get_rustflags_from_env( + gctx: &GlobalContext, + env_name: &'static str, +) -> Option> { + // First try CARGO_ENCODED_RUSTFLAGS from the environment. + // Prefer this over RUSTFLAGS since it's less prone to encoding errors. + if let Ok(a) = gctx.get_env(format!("CARGO_ENCODED_{}", env_name)) { + if a.is_empty() { + return Some(Vec::new()); + } + return Some(a.split('\x1f').map(str::to_string).collect()); + } + + // Then try RUSTFLAGS from the environment + if let Ok(a) = gctx.get_env(env_name) { + let args = a + .split(' ') + .map(str::trim) + .filter(|s| !s.is_empty()) + .map(str::to_string); + return Some(args.collect()); + } + + // No rustflags to be collected from the environment + None +} + #[cfg(test)] mod tests { use crate::GlobalContext; From 13ee124672c9bc2ad6b12b431408aaafbee3d708 Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Tue, 25 Aug 2026 14:58:06 +0100 Subject: [PATCH 4/7] feat(rustc): Add [CARGO_ENCODED_]RUSTFLAGS to the `Rustc` sysroot probe --- src/util/rustc.rs | 9 +++++++-- tests/testsuite/rustflags.rs | 24 ++++++++++++------------ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/util/rustc.rs b/src/util/rustc.rs index da8f92aaf1c..50696c668ac 100644 --- a/src/util/rustc.rs +++ b/src/util/rustc.rs @@ -166,9 +166,14 @@ impl Rustc { let mut cmd = self.workspace_process(); apply_env_config(gctx, &mut cmd)?; cmd.env(crate::CARGO_ENV, gctx.cargo_exe()?); + if let Some(rustflags) = get_rustflags_from_env(gctx, "RUSTFLAGS") { + cmd.args(&rustflags); + } cmd.arg("--print=sysroot"); - let (stdout, _) = self.cached_output(&cmd, 0)?; + let (stdout, _) = self + .cached_output(&cmd, 0) + .with_context(|| "failed to run `rustc` to find the sysroot location")?; let path: PathBuf = stdout.trim().into(); if !path.exists() { bail!("sysroot path \"{}\" does not exist", path.display()); @@ -451,6 +456,6 @@ mod tests { let rustc = gctx.load_global_rustc(None).unwrap(); let sysroot = rustc.sysroot(&gctx).unwrap(); - assert_ne!(sysroot, Path::new(".")); + assert_eq!(sysroot, Path::new(".")); } } diff --git a/tests/testsuite/rustflags.rs b/tests/testsuite/rustflags.rs index bce8a45fa59..7f15578e477 100644 --- a/tests/testsuite/rustflags.rs +++ b/tests/testsuite/rustflags.rs @@ -31,7 +31,7 @@ fn env_rustflags_normal_source() { .env("RUSTFLAGS", "-Z bogus") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -42,7 +42,7 @@ Caused by: .env("RUSTFLAGS", "-Z bogus") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -53,7 +53,7 @@ Caused by: .env("RUSTFLAGS", "-Z bogus") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -64,7 +64,7 @@ Caused by: .env("RUSTFLAGS", "-Z bogus") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -75,7 +75,7 @@ Caused by: .env("RUSTFLAGS", "-Z bogus") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -172,7 +172,7 @@ fn env_rustflags_normal_source_with_target() { .env("RUSTFLAGS", "-Z bogus") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -184,7 +184,7 @@ Caused by: .env("RUSTFLAGS", "-Z bogus") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -196,7 +196,7 @@ Caused by: .env("RUSTFLAGS", "-Z bogus") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -208,7 +208,7 @@ Caused by: .env("RUSTFLAGS", "-Z bogus") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -220,7 +220,7 @@ Caused by: .env("RUSTFLAGS", "-Z bogus") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -348,7 +348,7 @@ fn env_rustflags_recompile() { .env("RUSTFLAGS", "-Z bogus") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -367,7 +367,7 @@ fn env_rustflags_recompile2() { .env("RUSTFLAGS", "-Z bogus") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] From 5729ca62a44054e845013b098d3a254621a4d866 Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Tue, 25 Aug 2026 15:51:40 +0100 Subject: [PATCH 5/7] test(rustc): Test that the sysroot lookup respects build.rustflags --- src/util/rustc.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/util/rustc.rs b/src/util/rustc.rs index 50696c668ac..f9119e3ffeb 100644 --- a/src/util/rustc.rs +++ b/src/util/rustc.rs @@ -444,6 +444,7 @@ pub(crate) fn get_rustflags_from_env( #[cfg(test)] mod tests { use crate::GlobalContext; + use crate::context::{ConfigValue, Definition}; use crate::util::data_structures::HashMap; use std::path::Path; @@ -458,4 +459,29 @@ mod tests { let sysroot = rustc.sysroot(&gctx).unwrap(); assert_eq!(sysroot, Path::new(".")); } + + #[test] + fn sysroot_fetch_respects_build_rustflags() { + let mut gctx = GlobalContext::default().unwrap(); + gctx.set_env(HashMap::default()); + + let definition = Definition::Cli(None); + let rustflags = ConfigValue::List( + vec![ConfigValue::String( + "--sysroot=.".to_string(), + definition.clone(), + )], + definition.clone(), + ); + let build = ConfigValue::Table( + HashMap::from_iter([("rustflags".to_string(), rustflags)]), + definition, + ); + gctx.set_values(HashMap::from_iter([("build".to_string(), build)])) + .unwrap(); + + let rustc = gctx.load_global_rustc(None).unwrap(); + let sysroot = rustc.sysroot(&gctx).unwrap(); + assert_ne!(sysroot, Path::new(".")); + } } From a03dfe1d2e6adcfe7566b4d64c058e4b785cb925 Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Tue, 25 Aug 2026 16:01:51 +0100 Subject: [PATCH 6/7] refactor(rustc): Move build.rustflags helper function from target_info.rs to util/rustc.rs --- src/compiler/build_context/target_info.rs | 10 ++-------- src/util/rustc.rs | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/compiler/build_context/target_info.rs b/src/compiler/build_context/target_info.rs index 3955e319240..a5f017d7225 100644 --- a/src/compiler/build_context/target_info.rs +++ b/src/compiler/build_context/target_info.rs @@ -14,7 +14,7 @@ use crate::compiler::CrateType; use crate::compiler::apply_env_config; use crate::context::{GlobalContext, StringList, TargetConfig}; use crate::util::interning::InternedString; -use crate::util::rustc::get_rustflags_from_env; +use crate::util::rustc::{get_rustflags_from_build_config, get_rustflags_from_env}; use crate::util::{CargoResult, Rustc}; use crate::workspace::{Dependency, Package, Target, TargetKind, Workspace}; @@ -895,13 +895,7 @@ fn rustflags_from_host( /// Gets compiler flags from `[build]` section in the config. /// See [`extra_args`] for more. fn rustflags_from_build(gctx: &GlobalContext, flag: Flags) -> CargoResult>> { - // Then the `build.rustflags` value. - let build = gctx.build_config()?; - let list = match flag { - Flags::Rust => &build.rustflags, - Flags::Rustdoc => &build.rustdocflags, - }; - Ok(list.as_ref().map(|l| l.as_slice().to_vec())) + get_rustflags_from_build_config(gctx, matches!(flag, Flags::Rustdoc)) } /// Whether a host artifact must take its configuration solely from `[host]` and ignore `[target]`. diff --git a/src/util/rustc.rs b/src/util/rustc.rs index f9119e3ffeb..795022a0312 100644 --- a/src/util/rustc.rs +++ b/src/util/rustc.rs @@ -441,6 +441,21 @@ pub(crate) fn get_rustflags_from_env( None } +/// Gets compiler flags from `[build]` section in the config. +pub(crate) fn get_rustflags_from_build_config( + gctx: &GlobalContext, + is_rustdoc: bool, +) -> CargoResult>> { + // Then the `build.rustflags` value. + let build = gctx.build_config()?; + let list = if is_rustdoc { + &build.rustdocflags + } else { + &build.rustflags + }; + Ok(list.as_ref().map(|l| l.as_slice().to_vec())) +} + #[cfg(test)] mod tests { use crate::GlobalContext; From 14f29e38d747d0c152caddcc9d4d460f14bb78a9 Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Tue, 25 Aug 2026 16:22:26 +0100 Subject: [PATCH 7/7] feat(rustc): Add `build.rustflags` to the `Rustc` sysroot probe --- src/util/rustc.rs | 4 +++- tests/testsuite/rustflags.rs | 24 ++++++++++++------------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/util/rustc.rs b/src/util/rustc.rs index 795022a0312..52dd79c44d3 100644 --- a/src/util/rustc.rs +++ b/src/util/rustc.rs @@ -168,6 +168,8 @@ impl Rustc { cmd.env(crate::CARGO_ENV, gctx.cargo_exe()?); if let Some(rustflags) = get_rustflags_from_env(gctx, "RUSTFLAGS") { cmd.args(&rustflags); + } else if let Some(rustflags) = get_rustflags_from_build_config(gctx, false)? { + cmd.args(&rustflags); } cmd.arg("--print=sysroot"); @@ -497,6 +499,6 @@ mod tests { let rustc = gctx.load_global_rustc(None).unwrap(); let sysroot = rustc.sysroot(&gctx).unwrap(); - assert_ne!(sysroot, Path::new(".")); + assert_eq!(sysroot, Path::new(".")); } } diff --git a/tests/testsuite/rustflags.rs b/tests/testsuite/rustflags.rs index 7f15578e477..f823fa195d3 100644 --- a/tests/testsuite/rustflags.rs +++ b/tests/testsuite/rustflags.rs @@ -417,7 +417,7 @@ fn build_rustflags_normal_source() { p.cargo("check --lib") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -427,7 +427,7 @@ Caused by: p.cargo("check --bin=a") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -437,7 +437,7 @@ Caused by: p.cargo("check --example=b") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -447,7 +447,7 @@ Caused by: p.cargo("test") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -457,7 +457,7 @@ Caused by: p.cargo("bench") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -574,7 +574,7 @@ fn build_rustflags_normal_source_with_target() { .arg(host) .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -585,7 +585,7 @@ Caused by: .arg(host) .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -596,7 +596,7 @@ Caused by: .arg(host) .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -607,7 +607,7 @@ Caused by: .arg(host) .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -618,7 +618,7 @@ Caused by: .arg(host) .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -724,7 +724,7 @@ fn build_rustflags_recompile() { p.cargo("check") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..] @@ -751,7 +751,7 @@ fn build_rustflags_recompile2() { p.cargo("check") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] failed to run `rustc` to learn about target-specific information +[ERROR] failed to run `rustc` to find the sysroot location Caused by: [..]bogus[..]