Skip to content

Commit

Permalink
feat(trim-paths): rustc invocation integration
Browse files Browse the repository at this point in the history
  • Loading branch information
weihanglo committed Oct 27, 2023
1 parent d201ebd commit b913dea
Show file tree
Hide file tree
Showing 2 changed files with 206 additions and 55 deletions.
74 changes: 74 additions & 0 deletions src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -1162,6 +1168,74 @@ fn features_args(unit: &Unit) -> Vec<OsString> {
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:
// <https://github.com/rust-lang/rust/blob/c2ef3516/src/bootstrap/src/lib.rs#L1113-L1116>
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 `<pkg>-<version>`
//
// * 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`].
///
Expand Down
187 changes: 132 additions & 55 deletions tests/testsuite/profile_trim_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -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();
}

Expand All @@ -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")
Expand Down Expand Up @@ -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
// <https://github.com/rust-lang/cargo/pull/12625#discussion_r1371714791>
// 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());
}

0 comments on commit b913dea

Please sign in to comment.