diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 1b3337549d20..ce4b96ba3db1 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -94,6 +94,7 @@ use crate::util::errors::{CargoResult, VerboseError}; use crate::util::interning::InternedString; use crate::util::machine_message::{self, Message}; use crate::util::toml::TomlDebugInfo; +use crate::util::toml::TomlTrimPaths; use crate::util::{add_path_args, internal, iter_join_onto, profile}; use cargo_util::{paths, ProcessBuilder, ProcessError}; use rustfix::diagnostics::Applicability; @@ -950,6 +951,7 @@ fn build_base_args(cx: &Context<'_, '_>, cmd: &mut ProcessBuilder, unit: &Unit) incremental, strip, rustflags: profile_rustflags, + trim_paths, .. } = unit.profile.clone(); let test = unit.mode.is_any_test(); @@ -1028,6 +1030,10 @@ fn build_base_args(cx: &Context<'_, '_>, cmd: &mut ProcessBuilder, unit: &Unit) } } + if let Some(trim_paths) = trim_paths { + trim_paths_args(cmd, cx, unit, &trim_paths)?; + } + cmd.args(unit.pkg.manifest().lint_rustflags()); cmd.args(&profile_rustflags); if let Some(args) = cx.bcx.extra_args_for(unit) { @@ -1162,6 +1168,74 @@ fn features_args(unit: &Unit) -> Vec { args } +/// Generates the `--remap-path-scope` and `--remap-path-prefix` for [RFC 3127]. +/// See also unstable feature [`-Ztrim-paths`]. +/// +/// [RFC 3127]: https://rust-lang.github.io/rfcs/3127-trim-paths.html +/// [`-Ztrim-paths`]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#profile-trim-paths-option +fn trim_paths_args( + cmd: &mut ProcessBuilder, + cx: &Context<'_, '_>, + unit: &Unit, + trim_paths: &TomlTrimPaths, +) -> CargoResult<()> { + if trim_paths.is_none() { + return Ok(()); + } + + // feature gate was checked during mainfest/config parsing. + cmd.arg("-Zunstable-options"); + cmd.arg(format!("-Zremap-path-scope={trim_paths}")); + + let sysroot_remap = { + let sysroot = &cx.bcx.target_data.info(unit.kind).sysroot; + let mut remap = OsString::from("--remap-path-prefix="); + remap.push(sysroot); + remap.push("/lib/rustlib/src/rust"); // See also `detect_sysroot_src_path()`. + remap.push("="); + remap.push("/rustc/"); + // This remap logic aligns with rustc: + // + if let Some(commit_hash) = cx.bcx.rustc().commit_hash.as_ref() { + remap.push(commit_hash); + } else { + remap.push(cx.bcx.rustc().version.to_string()); + } + remap + }; + cmd.arg(sysroot_remap); + + let package_remap = { + let pkg_root = unit.pkg.root(); + let ws_root = cx.bcx.ws.root(); + let is_local = unit.pkg.package_id().source_id().is_path(); + let mut remap = OsString::from("--remap-path-prefix="); + // Remapped to path relative to workspace root: + // + // * path dependencies under workspace root directory + // + // Remapped to `-` + // + // * registry dependencies + // * git dependencies + // * path dependencies outside workspace root directory + if is_local && pkg_root.strip_prefix(ws_root).is_ok() { + remap.push(ws_root); + remap.push("="); // empty to remap to relative paths. + } else { + remap.push(pkg_root); + remap.push("="); + remap.push(unit.pkg.name()); + remap.push("-"); + remap.push(unit.pkg.version().to_string()); + } + remap + }; + cmd.arg(package_remap); + + Ok(()) +} + /// Generates the `--check-cfg` arguments for the `unit`. /// See unstable feature [`check-cfg`]. /// diff --git a/tests/testsuite/profile_trim_paths.rs b/tests/testsuite/profile_trim_paths.rs index 19d9670b2e6e..b3979bc2e326 100644 --- a/tests/testsuite/profile_trim_paths.rs +++ b/tests/testsuite/profile_trim_paths.rs @@ -78,8 +78,15 @@ fn release_profile_default_to_object() { p.cargo("build --release --verbose -Ztrim-paths") .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) - .with_stderr_does_not_contain("[..]-Zremap-path-scope=[..]") - .with_stderr_does_not_contain("[..]--remap-path-prefix=[..]") + .with_stderr( + "\ +[COMPILING] foo v0.0.1 ([CWD]) +[RUNNING] `rustc [..]\ + -Zremap-path-scope=object \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ + --remap-path-prefix=[CWD]= [..] +[FINISHED] release [..]", + ) .run(); } @@ -109,8 +116,15 @@ fn one_option() { for option in ["macro", "diagnostics", "object", "all"] { build(option) .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) - .with_stderr_does_not_contain("[..]-Zremap-path-scope=[..]") - .with_stderr_does_not_contain("[..]--remap-path-prefix=[..]") + .with_stderr(&format!( + "\ +[COMPILING] foo v0.0.1 ([CWD]) +[RUNNING] `rustc [..]\ + -Zremap-path-scope={option} \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ + --remap-path-prefix=[CWD]= [..] +[FINISHED] dev [..]", + )) .run(); } build("none") @@ -139,32 +153,15 @@ fn multiple_options() { p.cargo("build --verbose -Ztrim-paths") .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) - .with_stderr_does_not_contain("[..]-Zremap-path-scope=[..]") - .with_stderr_does_not_contain("[..]--remap-path-prefix=[..]") - .run(); -} - -#[cargo_test(nightly, reason = "-Zremap-path-scope is unstable")] -fn multiple_options_with_none() { - let p = project() - .file( - "Cargo.toml", - r#" - [package] - name = "foo" - version = "0.0.1" - - [profile.dev] - trim-paths = ["diagnostics", "macro", "object", "all", "none"] - "#, + .with_stderr( + "\ +[COMPILING] foo v0.0.1 ([CWD]) +[RUNNING] `rustc [..]\ + -Zremap-path-scope=diagnostics,macro,object \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ + --remap-path-prefix=[CWD]= [..] +[FINISHED] dev [..]", ) - .file("src/lib.rs", "") - .build(); - - p.cargo("build --verbose -Ztrim-paths") - .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) - .with_stderr_does_not_contain("[..]-Zremap-path-scope=[..]") - .with_stderr_does_not_contain("[..]--remap-path-prefix=[..]") .run(); } @@ -193,13 +190,29 @@ fn registry_dependency() { .build(); let registry_src = paths::home().join(".cargo/registry/src"); - let registry_src = registry_src.display(); + let pkg_remap = format!("{}/[..]/bar-0.0.1=bar-0.0.1", registry_src.display()); p.cargo("run --verbose -Ztrim-paths") .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) - .with_stdout(format!("{registry_src}/[..]/bar-0.0.1/src/lib.rs")) - .with_stderr_does_not_contain("[..]-Zremap-path-scope=[..]") - .with_stderr_does_not_contain("[..]--remap-path-prefix=[..]") + .with_stdout("bar-0.0.1/src/lib.rs") + .with_stderr(&format!( + "\ +[UPDATING] [..] +[DOWNLOADING] crates ... +[DOWNLOADED] bar v0.0.1 ([..]) +[COMPILING] bar v0.0.1 +[RUNNING] `rustc [..]\ + -Zremap-path-scope=object \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ + --remap-path-prefix={pkg_remap} [..] +[COMPILING] foo v0.0.1 ([CWD]) +[RUNNING] `rustc [..]\ + -Zremap-path-scope=object \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ + --remap-path-prefix=[CWD]= [..] +[FINISHED] dev [..] +[RUNNING] `target/debug/foo[EXE]`" + )) .run(); } @@ -233,13 +246,27 @@ fn git_dependency() { .build(); let git_checkouts_src = paths::home().join(".cargo/git/checkouts"); - let git_checkouts_src = git_checkouts_src.display(); + let pkg_remap = format!("{}/bar-[..]/[..]=bar-0.0.1", git_checkouts_src.display()); p.cargo("run --verbose -Ztrim-paths") .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) - .with_stdout(format!("{git_checkouts_src}/bar-[..]/[..]/src/lib.rs")) - .with_stderr_does_not_contain("[..]-Zremap-path-scope=[..]") - .with_stderr_does_not_contain("[..]--remap-path-prefix=[..]") + .with_stdout("bar-0.0.1/src/lib.rs") + .with_stderr(&format!( + "\ +[UPDATING] git repository `{url}` +[COMPILING] bar v0.0.1 ({url}[..]) +[RUNNING] `rustc [..]\ + -Zremap-path-scope=object \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ + --remap-path-prefix={pkg_remap} [..] +[COMPILING] foo v0.0.1 ([CWD]) +[RUNNING] `rustc [..]\ + -Zremap-path-scope=object \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ + --remap-path-prefix=[CWD]= [..] +[FINISHED] dev [..] +[RUNNING] `target/debug/foo[EXE]`" + )) .run(); } @@ -271,8 +298,21 @@ fn path_dependency() { p.cargo("run --verbose -Ztrim-paths") .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) .with_stdout("cocktail-bar/src/lib.rs") - .with_stderr_does_not_contain("[..]-Zremap-path-scope=[..]") - .with_stderr_does_not_contain("[..]--remap-path-prefix=[..]") + .with_stderr(&format!( + "\ +[COMPILING] bar v0.0.1 ([..]/cocktail-bar) +[RUNNING] `rustc [..]\ + -Zremap-path-scope=object \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ + --remap-path-prefix=[CWD]= [..] +[COMPILING] foo v0.0.1 ([CWD]) +[RUNNING] `rustc [..]\ + -Zremap-path-scope=object \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ + --remap-path-prefix=[CWD]= [..] +[FINISHED] dev [..] +[RUNNING] `target/debug/foo[EXE]`" + )) .run(); } @@ -306,9 +346,22 @@ fn path_dependency_outside_workspace() { p.cargo("run --verbose -Ztrim-paths") .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) - .with_stdout(format!("{bar_path}/src/lib.rs")) - .with_stderr_does_not_contain("[..]-Zremap-path-scope=[..]") - .with_stderr_does_not_contain("[..]--remap-path-prefix=[..]") + .with_stdout("bar-0.0.1/src/lib.rs") + .with_stderr(&format!( + "\ +[COMPILING] bar v0.0.1 ([..]/bar) +[RUNNING] `rustc [..]\ + -Zremap-path-scope=object \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ + --remap-path-prefix={bar_path}=bar-0.0.1 [..] +[COMPILING] foo v0.0.1 ([CWD]) +[RUNNING] `rustc [..]\ + -Zremap-path-scope=object \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ + --remap-path-prefix=[CWD]= [..] +[FINISHED] dev [..] +[RUNNING] `target/debug/foo[EXE]`" + )) .run(); } @@ -337,22 +390,34 @@ fn diagnostics_works() { .build(); let registry_src = paths::home().join(".cargo/registry/src"); - let registry_src = registry_src.display(); + let pkg_remap = format!("{}/[..]/bar-0.0.1=bar-0.0.1", registry_src.display()); p.cargo("build -vv -Ztrim-paths") .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) - .with_stderr_contains(format!( + .with_stderr_contains( "\ warning: unused variable: `unused` - --> {registry_src}/[..]/bar-0.0.1/src/lib.rs:1:18 + --> bar-0.0.1/src/lib.rs:1:18 | -1 | pub fn f() {{ let unused = 0; }} +1 | pub fn f() { let unused = 0; } | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused` | = note: `#[warn(unused_variables)]` on by default", + ) + .with_stderr_contains(&format!( + "\ +[RUNNING] [..]rustc [..]\ + -Zremap-path-scope=diagnostics \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ + --remap-path-prefix={pkg_remap} [..]", )) - .with_stderr_does_not_contain("[..]-Zremap-path-scope=[..]") - .with_stderr_does_not_contain("[..]--remap-path-prefix=[..]") + .with_stderr_contains( + "\ +[RUNNING] [..]rustc [..]\ + -Zremap-path-scope=diagnostics \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ + --remap-path-prefix=[CWD]= [..]", + ) .run(); } @@ -370,6 +435,8 @@ fn object_works() { }; let registry_src = paths::home().join(".cargo/registry/src"); + let pkg_remap = format!("{}/[..]/bar-0.0.1=bar-0.0.1", registry_src.display()); + let rust_src = "/lib/rustc/src/rust".as_bytes(); let registry_src_bytes = registry_src.as_os_str().as_bytes(); Package::new("bar", "0.0.1") @@ -425,16 +492,26 @@ fn object_works() { p.cargo("build --verbose -Ztrim-paths") .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) - .with_stderr_does_not_contain("[..]-Zremap-path-scope=[..]") - .with_stderr_does_not_contain("[..]--remap-path-prefix=[..]") + .with_stderr(&format!( + "\ +[COMPILING] bar v0.0.1 +[RUNNING] `rustc [..]\ + -Zremap-path-scope=object \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ + --remap-path-prefix={pkg_remap} [..] +[COMPILING] foo v0.0.1 ([CWD]) +[RUNNING] `rustc [..]\ + -Zremap-path-scope=object \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ + --remap-path-prefix=[CWD]= [..] +[FINISHED] dev [..]", + )) .run(); let bin_path = p.bin("foo"); assert!(bin_path.is_file()); let stdout = run_readelf(bin_path).stdout; - // TODO: re-enable this check when rustc bootstrap disables remapping - // - // assert!(memchr::memmem::find(&stdout, rust_src).is_some()); - assert!(memchr::memmem::find(&stdout, registry_src_bytes).is_some()); - assert!(memchr::memmem::find(&stdout, pkg_root).is_some()); + assert!(memchr::memmem::find(&stdout, rust_src).is_none()); + assert!(memchr::memmem::find(&stdout, registry_src_bytes).is_none()); + assert!(memchr::memmem::find(&stdout, pkg_root).is_none()); }