Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 51 additions & 12 deletions src/compiler/trim_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ pub(crate) const UNREMAP_SUFFIX: &str = ".trim-paths.jsonl";
/// See <https://github.com/rust-lang/cargo/issues/17309>.
pub(crate) const WS_REMAP_ENV: &str = "__CARGO_RUSTC_BOOTSTRAP_WS_REMAP";

/// A single `<from>=<to>` remap rule.
type RemapPair = (PathBuf, String);

/// Like [`trim_paths_args`] but for rustdoc invocations.
pub(crate) fn trim_paths_args_rustdoc(
cmd: &mut ProcessBuilder,
Expand Down Expand Up @@ -103,15 +106,19 @@ pub(crate) fn trim_paths_args(
/// **†**: path dependencies outside the workspace and other uncategorized dependencies.
///
/// [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] {
[
join_remap(package_remap(build_runner, unit)),
join_remap(build_dir_remap(build_runner)),
join_remap(sysroot_remap(build_runner)),
]
pub(crate) fn trim_paths_remap(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> Vec<OsString> {
let package = package_remap(build_runner, unit);
let workspace_relative = custom_workspace_relative_remap(unit, &package);

let mut remaps = Vec::with_capacity(4);
remaps.push(join_remap(package));
remaps.extend(workspace_relative.map(join_remap));
remaps.push(join_remap(build_dir_remap(build_runner)));
remaps.push(join_remap(sysroot_remap(build_runner)));
remaps
}

fn join_remap((from, to): (PathBuf, String)) -> OsString {
fn join_remap((from, to): RemapPair) -> OsString {
let mut remap = OsString::with_capacity(from.as_os_str().len() + 1 + to.len());
remap.push(from);
remap.push("=");
Expand All @@ -123,7 +130,7 @@ fn join_remap((from, to): (PathBuf, String)) -> OsString {
///
/// This remap logic aligns with rustc:
/// <https://github.com/rust-lang/rust/blob/c2ef3516/src/bootstrap/src/lib.rs#L1113-L1116>
fn sysroot_remap(build_runner: &BuildRunner<'_, '_>) -> (PathBuf, String) {
fn sysroot_remap(build_runner: &BuildRunner<'_, '_>) -> RemapPair {
// See also `detect_sysroot_src_path()`.
let sysroot = build_runner
.bcx
Expand All @@ -142,7 +149,7 @@ fn sysroot_remap(build_runner: &BuildRunner<'_, '_>) -> (PathBuf, String) {
}

/// Path prefix remap rules for dependencies.
fn package_remap(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> (PathBuf, String) {
fn package_remap(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> RemapPair {
let pkg_root = unit.pkg.root();
let ws_root = build_runner.bcx.ws.root();
let source_id = unit.pkg.package_id().source_id();
Expand Down Expand Up @@ -175,7 +182,7 @@ fn package_remap(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> (PathBuf, S
}

/// Path prefix remap rules for dependencies within workspaces.
fn workspace_remap(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> (PathBuf, String) {
fn workspace_remap(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> RemapPair {
let ws_root = build_runner.bcx.ws.root();
// rustc working directory is usually workspace root.
// However, when `-Zroot-dir` is set, it may not be.
Expand All @@ -199,6 +206,38 @@ fn workspace_remap(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> (PathBuf,
(from, to)
}

/// Extra remap rule for relative workspace member paths.
///
/// Cargo passes member source paths relative to the working directory (see [`path_args`]),
/// so the absolute [`workspace_remap`] rule never covers them.
///
/// When custom prefix for workspace remap is set via [`WS_REMAP_ENV`],
/// an extra remap rule for relative member paths is required for correctly
/// adding prefix to member paths.
fn custom_workspace_relative_remap(unit: &Unit, (from, to): &RemapPair) -> Option<RemapPair> {
// `to` staying as `.` means WS_REMAP_ENV didn't kick in.
if to == "." {
return None;
}

if !unit.pkg.package_id().source_id().is_path() {
return None;
}

let rel = unit.pkg.root().strip_prefix(from).ok()?;
if rel.as_os_str().is_empty() {
return None;
}

let mut rel_to = to.clone();
for comp in rel.components() {
// e.g., library -> <custom-prefix>/library
rel_to.push('/');
rel_to.push_str(&comp.as_os_str().to_string_lossy());
}
Some((rel.to_path_buf(), rel_to))
}

/// Finds the checkout root and revision directory name of a git dependency.
///
/// This is built under this layout: `$CARGO_HOME/git/checkouts/<repo>-<hash>[-shallow]/<rev>`.
Expand Down Expand Up @@ -231,7 +270,7 @@ fn git_checkout<'a>(
/// [`file!`] macro in-place via the `OUT_DIR` environment.
/// * On Linux, `DW_AT_GNU_dwo_name` that contains paths to split debuginfo
/// files (dwp and dwo).
fn build_dir_remap(build_runner: &BuildRunner<'_, '_>) -> (PathBuf, String) {
fn build_dir_remap(build_runner: &BuildRunner<'_, '_>) -> RemapPair {
let from = build_runner.bcx.ws.build_dir().into_path_unlocked();
let to = "/cargo/build-dir".to_owned();
(from, to)
Expand Down Expand Up @@ -280,7 +319,7 @@ pub(crate) fn write_unremap_file(
) -> CargoResult<()> {
let mut remaps = BTreeMap::new();

let mut insert = |(from, to): (PathBuf, String)| match remaps.entry(to) {
let mut insert = |(from, to): RemapPair| match remaps.entry(to) {
Entry::Vacant(entry) => {
entry.insert(from);
}
Expand Down
10 changes: 9 additions & 1 deletion tests/testsuite/profile_trim_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1640,19 +1640,27 @@ fn workspace_prefix_override_from_env() {
version = "0.0.1"
edition = "2015"

[dependencies]
member = { path = "member" }

[profile.dev]
trim-paths = "object"
"#,
)
.file("src/main.rs", "fn main() {}")
.file("member/Cargo.toml", &basic_manifest("member", "0.0.1"))
.file("member/src/lib.rs", "")
.build();

p.cargo("build --verbose -Ztrim-paths")
.env("__CARGO_RUSTC_BOOTSTRAP_WS_REMAP", "/rustc-dev/1111111")
.masquerade_as_nightly_cargo(&["-Ztrim-paths"])
.with_stderr_data(str![[r#"
[LOCKING] 1 package to highest compatible version
[COMPILING] member v0.0.1 ([ROOT]/foo/member)
[RUNNING] `rustc [..]--remap-path-prefix=[ROOT]/foo=/rustc-dev/1111111 --remap-path-prefix=member=/rustc-dev/1111111/member --remap-path-prefix=[ROOT]/foo/target=/cargo/build-dir [..]`
[COMPILING] foo v0.0.1 ([ROOT]/foo)
[RUNNING] `rustc [..]--remap-path-prefix=[ROOT]/foo=/rustc-dev/1111111 [..]`
[RUNNING] `rustc [..]--remap-path-prefix=[ROOT]/foo=/rustc-dev/1111111 --remap-path-prefix=[ROOT]/foo/target=/cargo/build-dir [..]`
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s

"#]])
Expand Down