From 63cef2c4fc8389a7c583ace1353bc68c5a44af01 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Wed, 6 Sep 2023 21:59:01 +0800 Subject: [PATCH] feat(trim-paths): rustc invocation integration --- src/cargo/core/compiler/mod.rs | 74 ++++++++++++ tests/testsuite/profile_trim_paths.rs | 163 +++++++++++++++++++++----- 2 files changed, 208 insertions(+), 29 deletions(-) diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 1b3337549d2..ce4b96ba3db 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 afc70ec2ad4..b0b8d9577a4 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,8 +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=[..]") + .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 [..]", + ) .run(); } @@ -169,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(); } @@ -209,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(); } @@ -247,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(); } @@ -282,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(); } @@ -314,13 +391,29 @@ fn diagnostics_works() { let registry_src = paths::home().join(".cargo/registry/src"); let registry_src = registry_src.display(); + let pkg_remap = format!("{registry_src}/[..]/bar-0.0.1=bar-0.0.1"); p.cargo("build -vv -Ztrim-paths") .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) - .with_stderr_contains(format!("[..]{registry_src}/[..]/bar-0.0.1/src/lib.rs:1[..]")) + .with_stderr_line_without( + &["[..]bar-0.0.1/src/lib.rs:1[..]"], + &[&format!("{registry_src}")], + ) .with_stderr_contains("[..]unused_variables[..]") - .with_stderr_does_not_contain("[..]-Zremap-path-scope=[..]") - .with_stderr_does_not_contain("[..]--remap-path-prefix=[..]") + .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_contains( + "\ +[RUNNING] [..]rustc [..]\ + -Zremap-path-scope=diagnostics \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ + --remap-path-prefix=[CWD]= [..]", + ) .run(); } @@ -338,6 +431,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") @@ -393,16 +488,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()); }