From bb6de5c34e4c23cbb5c3e75daf26aaaf5fbe6073 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sat, 13 Jun 2026 09:49:48 -0400 Subject: [PATCH 1/4] refactor(trim-paths): split remap computation from rustflags Extract the `=` pair computation into `trim_paths_remap` so it can be reused beyond `--remap-path-prefix` flag. --- src/cargo/core/compiler/mod.rs | 40 +++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index dfe4802ceed..1cad827db1e 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -1511,11 +1511,11 @@ fn trim_paths_args_rustdoc( // feature gate was checked during manifest/config parsing. cmd.arg("-Zunstable-options"); - // Order of `--remap-path-prefix` flags is important for `-Zbuild-std`. - // We want to show `/rustc//library/std` instead of `std-0.0.0`. - cmd.arg(package_remap(build_runner, unit)); - cmd.arg(build_dir_remap(build_runner)); - cmd.arg(sysroot_remap(build_runner, unit)); + for pair in trim_paths_remap(build_runner, unit) { + let mut arg = OsString::from("--remap-path-prefix="); + arg.push(pair); + cmd.arg(arg); + } Ok(()) } @@ -1538,21 +1538,35 @@ fn trim_paths_args( // feature gate was checked during manifest/config parsing. cmd.arg(format!("--remap-path-scope={trim_paths}")); - // Order of `--remap-path-prefix` flags is important for `-Zbuild-std`. - // We want to show `/rustc//library/std` instead of `std-0.0.0`. - cmd.arg(package_remap(build_runner, unit)); - cmd.arg(build_dir_remap(build_runner)); - cmd.arg(sysroot_remap(build_runner, unit)); + for pair in trim_paths_remap(build_runner, unit) { + let mut arg = OsString::from("--remap-path-prefix="); + arg.push(pair); + cmd.arg(arg); + } Ok(()) } +/// Computes the `=` path remap pairs for [RFC 3127] trim-paths. +/// +/// Order of `--remap-path-prefix` flags is important for `-Zbuild-std`. +/// We want to show `/rustc//library/std` instead of `std-0.0.0`. +/// +/// [RFC 3127]: https://rust-lang.github.io/rfcs/3127-trim-paths.html +pub(crate) fn trim_paths_remap(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> [OsString; 3] { + [ + package_remap(build_runner, unit), + build_dir_remap(build_runner), + sysroot_remap(build_runner, unit), + ] +} + /// Path prefix remap rules for sysroot. /// /// This remap logic aligns with rustc: /// fn sysroot_remap(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> OsString { - let mut remap = OsString::from("--remap-path-prefix="); + let mut remap = OsString::new(); remap.push({ // See also `detect_sysroot_src_path()`. let mut sysroot = build_runner.bcx.target_data.info(unit.kind).sysroot.clone(); @@ -1582,7 +1596,7 @@ fn sysroot_remap(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> OsString { fn package_remap(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> OsString { let pkg_root = unit.pkg.root(); let ws_root = build_runner.bcx.ws.root(); - let mut remap = OsString::from("--remap-path-prefix="); + let mut remap = OsString::new(); let source_id = unit.pkg.package_id().source_id(); if source_id.is_git() { remap.push( @@ -1629,7 +1643,7 @@ fn package_remap(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> OsString { /// files (dwp and dwo). fn build_dir_remap(build_runner: &BuildRunner<'_, '_>) -> OsString { let build_dir = build_runner.bcx.ws.build_dir(); - let mut remap = OsString::from("--remap-path-prefix="); + let mut remap = OsString::new(); remap.push(build_dir.as_path_unlocked()); remap.push("=/cargo/build-dir"); remap From 6626676b43e286f66cbd93b645f35270d99ec8f4 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sat, 13 Jun 2026 09:53:36 -0400 Subject: [PATCH 2/4] fix(trim-paths): rename CARGO_TRIM_PATHS Rename CARGO_TRIM_PATHS to `CARGO_TRIM_PATHS_SCOPE` to make room for a forthcoming `CARGO_TRIM_PATHS_REMAP`. --- src/cargo/core/compiler/custom_build.rs | 2 +- src/doc/src/reference/unstable.md | 2 +- tests/testsuite/profile_trim_paths.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cargo/core/compiler/custom_build.rs b/src/cargo/core/compiler/custom_build.rs index f4f77b70950..060dd2fc52b 100644 --- a/src/cargo/core/compiler/custom_build.rs +++ b/src/cargo/core/compiler/custom_build.rs @@ -399,7 +399,7 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul } if let Some(trim_paths) = unit.profile.trim_paths.as_ref() { - cmd.env("CARGO_TRIM_PATHS", trim_paths.to_string()); + cmd.env("CARGO_TRIM_PATHS_SCOPE", trim_paths.to_string()); } // Be sure to pass along all enabled features for this package, this is the diff --git a/src/doc/src/reference/unstable.md b/src/doc/src/reference/unstable.md index 139b7f7491e..4e28e545747 100644 --- a/src/doc/src/reference/unstable.md +++ b/src/doc/src/reference/unstable.md @@ -1566,7 +1566,7 @@ This will not affect any hard-coded paths in the source code, such as in strings *as a new entry of ["Environment variables Cargo sets for build scripts"](./environment-variables.md#environment-variables-cargo-sets-for-crates)* -* `CARGO_TRIM_PATHS` --- The value of `trim-paths` profile option. +* `CARGO_TRIM_PATHS_SCOPE` --- The value of `trim-paths` profile option. `false`, `"none"`, and empty arrays would be converted to `none`. `true` and `"all"` become `all`. Values in a non-empty array would be joined into a comma-separated list. diff --git a/tests/testsuite/profile_trim_paths.rs b/tests/testsuite/profile_trim_paths.rs index f89bdb32942..2104fe428d6 100644 --- a/tests/testsuite/profile_trim_paths.rs +++ b/tests/testsuite/profile_trim_paths.rs @@ -767,7 +767,7 @@ fn custom_build_env_var_trim_paths() { r#" fn main() {{ assert_eq!( - std::env::var("CARGO_TRIM_PATHS").unwrap().as_str(), + std::env::var("CARGO_TRIM_PATHS_SCOPE").unwrap().as_str(), "{expected}", ); }} From cfccbd38967f29f37ea08c654a139d3bbb04fe24 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sat, 13 Jun 2026 12:10:06 -0400 Subject: [PATCH 3/4] test(trim-paths): assert CARGO_TRIM_PATHS_REMAP is absent --- tests/testsuite/profile_trim_paths.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/testsuite/profile_trim_paths.rs b/tests/testsuite/profile_trim_paths.rs index 2104fe428d6..0ab5314fd6e 100644 --- a/tests/testsuite/profile_trim_paths.rs +++ b/tests/testsuite/profile_trim_paths.rs @@ -770,6 +770,10 @@ fn custom_build_env_var_trim_paths() { std::env::var("CARGO_TRIM_PATHS_SCOPE").unwrap().as_str(), "{expected}", ); + assert_eq!( + std::env::var("CARGO_TRIM_PATHS_REMAP"), + Err(std::env::VarError::NotPresent), + ); }} "# ), From af32b7c707820ab053da1390231055b34763243b Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sat, 13 Jun 2026 12:12:17 -0400 Subject: [PATCH 4/4] feat(trim-paths): emit `CARGO_TRIM_PATHS_REMAP` for build.rs Build scripts may invoke C/C++ compilers that embed local absolute paths into their output, which `trim-paths` would otherwise miss. This exposes the same `=` remap pairs Cargo passes to rustc as a build script environment variable, so build scripts can forward them like via `-ffile-prefix-map`. Part of rust-lang/cargo#12137. See also https://github.com/rust-lang/all-hands-2026/issues/38#issuecomment-4519021044 --- src/cargo/core/compiler/custom_build.rs | 7 +++++++ src/doc/src/reference/unstable.md | 6 ++++++ tests/testsuite/profile_trim_paths.rs | 26 +++++++++++++++++-------- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/cargo/core/compiler/custom_build.rs b/src/cargo/core/compiler/custom_build.rs index 060dd2fc52b..f46c58cf4ce 100644 --- a/src/cargo/core/compiler/custom_build.rs +++ b/src/cargo/core/compiler/custom_build.rs @@ -400,6 +400,13 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul if let Some(trim_paths) = unit.profile.trim_paths.as_ref() { cmd.env("CARGO_TRIM_PATHS_SCOPE", trim_paths.to_string()); + if !trim_paths.is_none() { + let pairs = super::trim_paths_remap(build_runner, unit); + cmd.env( + "CARGO_TRIM_PATHS_REMAP", + paths::join_paths(&pairs, "CARGO_TRIM_PATHS_REMAP")?, + ); + } } // Be sure to pass along all enabled features for this package, this is the diff --git a/src/doc/src/reference/unstable.md b/src/doc/src/reference/unstable.md index 4e28e545747..fe5e7f3ebf7 100644 --- a/src/doc/src/reference/unstable.md +++ b/src/doc/src/reference/unstable.md @@ -1574,6 +1574,12 @@ This will not affect any hard-coded paths in the source code, such as in strings the user may request them to be sanitized in different types of artifacts. Common paths requiring sanitization include `OUT_DIR`, `CARGO_MANIFEST_DIR` and `CARGO_MANIFEST_PATH`, plus any other introduced by the build script, such as include directories. +* `CARGO_TRIM_PATHS_REMAP` --- The `=` path remap pairs Cargo passes to the compiler, + joined by the platform path separator. + Only set when `trim-paths` profile is active. + Build scripts can forward these mappings to C/C++ compilers and other tools, + for example via `cc`'s `-ffile-prefix-map`, + to sanitize paths consistently with the rest of the build. ## gc diff --git a/tests/testsuite/profile_trim_paths.rs b/tests/testsuite/profile_trim_paths.rs index 0ab5314fd6e..638c077a72f 100644 --- a/tests/testsuite/profile_trim_paths.rs +++ b/tests/testsuite/profile_trim_paths.rs @@ -766,14 +766,24 @@ fn custom_build_env_var_trim_paths() { &format!( r#" fn main() {{ - assert_eq!( - std::env::var("CARGO_TRIM_PATHS_SCOPE").unwrap().as_str(), - "{expected}", - ); - assert_eq!( - std::env::var("CARGO_TRIM_PATHS_REMAP"), - Err(std::env::VarError::NotPresent), - ); + let scope = std::env::var("CARGO_TRIM_PATHS_SCOPE").unwrap(); + assert_eq!(scope.as_str(), "{expected}"); + + let remap = std::env::var_os("CARGO_TRIM_PATHS_REMAP"); + if scope == "none" {{ + assert_eq!(remap, None); + }} else {{ + let remap = remap.unwrap(); + let pairs: Vec = std::env::split_paths(&remap) + .map(|p| p.into_os_string().into_string().unwrap()) + .collect(); + // package, build-dir, sysroot + assert_eq!(pairs.len(), 3, "remap = {{remap:?}}"); + // The package lives at the workspace root, remapped to `.`. + assert!(pairs[0].ends_with("=."), "remap = {{remap:?}}"); + assert!(pairs[1].ends_with("=/cargo/build-dir"), "remap = {{remap:?}}"); + assert!(pairs[2].contains("=/rustc/"), "remap = {{remap:?}}"); + }} }} "# ),