diff --git a/doc/book/src/reference/unstable.md b/doc/book/src/reference/unstable.md index 80599ba093c..90af45a83a2 100644 --- a/doc/book/src/reference/unstable.md +++ b/doc/book/src/reference/unstable.md @@ -1549,11 +1549,32 @@ But the paths to these separate files are sanitized. If `trim-paths` is not `none` or `false`, then the following paths are sanitized if they appear in a selected scope: -1. Path to the source files of the standard and core library (sysroot) will begin with `/rustc/[rustc commit hash]`, +1. Path to the source files of the standard and core library (sysroot) will begin with `/rustc/`, e.g. `/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs` -> `/rustc/fe72845f7bb6a77b9e671e6a4f32fe714962cec4/library/core/src/result.rs` -2. Path to the current package will be stripped, relatively to the current workspace root, e.g. `/home/username/crate/src/lib.rs` -> `src/lib.rs`. -3. Path to dependency packages will be replaced with `[package name]-[version]`. E.g. `/home/username/deps/foo/src/lib.rs` -> `foo-0.1.0/src/lib.rs` +2. Path to the current package will be stripped, + relatively to the current workspace root, + e.g. `/home/username/crate/src/lib.rs` -> `src/lib.rs`. + This also covers path dependencies located inside the workspace directory. +3. Path to a registry dependency will begin with `/cargo/registry/`, + which replaces the registry's extraction directory, + e.g. `/home/username/.cargo/registry/src/index.crates.io-6f17d22d3f0a95d1/foo-0.1.0/src/lib.rs` -> + `/cargo/registry/6f17d22d3f0a95d1/foo-0.1.0/src/lib.rs`. +4. Path to a git dependency will begin with `/cargo/git//`, + which replaces the checkout directory. + `` is a prefix of the resolved commit ID recorded in the lockfile. +5. Path to a path dependency outside the workspace will be replaced with + `/cargo/path/-`. +6. Path into the build directory, for example `OUT_DIR` generated sources, + will begin with `/cargo/build-dir`. + +`` and `` are opaque stable hashes of the dependency's source. + +Vendored copies of registry or git dependencies +(via [source replacement](./source-replacement.md)) +are sanitized by their file location instead, +like workspace paths when inside the workspace directory, +otherwise like path dependencies. When a path to the source files of the standard and core library is *not* in scope for sanitization, the emitted path will depend on if `rust-src` component is present. diff --git a/src/compiler/custom_build.rs b/src/compiler/custom_build.rs index a5ca1156e6f..2db3e6b86e0 100644 --- a/src/compiler/custom_build.rs +++ b/src/compiler/custom_build.rs @@ -403,7 +403,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_SCOPE", trim_paths.to_string()); if !trim_paths.is_none() { - let pairs = super::trim_paths_remap(build_runner, unit); + let pairs = super::trim_paths::trim_paths_remap(build_runner, unit); cmd.env( "CARGO_TRIM_PATHS_REMAP", paths::join_paths(&pairs, "CARGO_TRIM_PATHS_REMAP")?, diff --git a/src/compiler/mod.rs b/src/compiler/mod.rs index 3f406a15e93..ba3f9fd181f 100644 --- a/src/compiler/mod.rs +++ b/src/compiler/mod.rs @@ -48,6 +48,7 @@ mod output_sbom; pub mod rustdoc; pub mod standard_lib; pub mod timings; +mod trim_paths; mod unit; pub mod unit_dependencies; pub mod unit_graph; @@ -95,6 +96,8 @@ pub(crate) use self::layout::Layout; pub use self::lto::Lto; use self::output_depinfo::output_depinfo; use self::output_sbom::build_sbom; +use self::trim_paths::trim_paths_args; +use self::trim_paths::trim_paths_args_rustdoc; use self::unit_graph::UnitDep; use crate::compiler::future_incompat::FutureIncompatReport; @@ -115,8 +118,6 @@ use crate::workspace::{Feature, PackageId, Target}; use cargo_util::{ProcessBuilder, ProcessError, paths}; use cargo_util_schemas::manifest::TomlDebugInfo; -use cargo_util_schemas::manifest::TomlTrimPaths; -use cargo_util_schemas::manifest::TomlTrimPathsValue; use cargo_util_terminal::Verbosity; use rustfix::diagnostics::Applicability; @@ -1525,159 +1526,6 @@ fn features_args(unit: &Unit) -> Vec { args } -/// Like [`trim_paths_args`] but for rustdoc invocations. -fn trim_paths_args_rustdoc( - cmd: &mut ProcessBuilder, - build_runner: &BuildRunner<'_, '_>, - unit: &Unit, - trim_paths: &TomlTrimPaths, -) -> CargoResult<()> { - match trim_paths { - // rustdoc supports diagnostics trimming only. - TomlTrimPaths::Values(values) if !values.contains(&TomlTrimPathsValue::Diagnostics) => { - return Ok(()); - } - _ => {} - } - - for pair in trim_paths_remap(build_runner, unit) { - let mut arg = OsString::from("--remap-path-prefix="); - arg.push(pair); - cmd.arg(arg); - } - - Ok(()) -} - -/// 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, - build_runner: &BuildRunner<'_, '_>, - unit: &Unit, - trim_paths: &TomlTrimPaths, -) -> CargoResult<()> { - if trim_paths.is_none() { - return Ok(()); - } - - // feature gate was checked during manifest/config parsing. - cmd.arg(format!("--remap-path-scope={trim_paths}")); - - 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::new(); - remap.push({ - // See also `detect_sysroot_src_path()`. - let mut sysroot = build_runner.bcx.target_data.info(unit.kind).sysroot.clone(); - sysroot.push("lib"); - sysroot.push("rustlib"); - sysroot.push("src"); - sysroot.push("rust"); - sysroot - }); - remap.push("="); - remap.push("/rustc/"); - if let Some(commit_hash) = build_runner.bcx.rustc().commit_hash.as_ref() { - remap.push(commit_hash); - } else { - remap.push(build_runner.bcx.rustc().version.to_string()); - } - remap -} - -/// Path prefix remap rules for dependencies. -/// -/// * Git dependencies: remove `~/.cargo/git/checkouts` prefix. -/// * Registry dependencies: remove `~/.cargo/registry/src` prefix. -/// * Others (e.g. path dependencies): -/// * relative paths to workspace root if inside the workspace directory. -/// * otherwise remapped to `-`. -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::new(); - let source_id = unit.pkg.package_id().source_id(); - if source_id.is_git() { - remap.push( - build_runner - .bcx - .gctx - .git_checkouts_path() - .as_path_unlocked(), - ); - remap.push("="); - } else if source_id.is_registry() { - remap.push( - build_runner - .bcx - .gctx - .registry_source_path() - .as_path_unlocked(), - ); - remap.push("="); - } else if pkg_root.strip_prefix(ws_root).is_ok() { - remap.push(ws_root); - remap.push("=."); // remap to relative rustc work dir explicitly - } else { - remap.push(pkg_root); - remap.push("="); - remap.push(unit.pkg.name()); - remap.push("-"); - remap.push(unit.pkg.version().to_string()); - } - remap -} - -/// Remap all paths pointing to `build.build-dir`, -/// i.e., `[BUILD_DIR]/debug/deps/foo-[HASH].dwo` would be remapped to -/// `/cargo/build-dir/debug/deps/foo-[HASH].dwo` -/// (note the `/cargo/build-dir` prefix). -/// -/// This covers scenarios like: -/// -/// * Build script generated code. For example, a build script may call `file!` -/// macros, and the associated crate uses [`include!`] to include the expanded -/// [`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<'_, '_>) -> OsString { - let build_dir = build_runner.bcx.ws.build_dir(); - let mut remap = OsString::new(); - remap.push(build_dir.as_path_unlocked()); - remap.push("=/cargo/build-dir"); - remap -} - /// Generates the `--check-cfg` arguments for the `unit`. fn check_cfg_args(unit: &Unit) -> Vec { // The routine below generates the --check-cfg arguments. Our goals here are to diff --git a/src/compiler/trim_paths.rs b/src/compiler/trim_paths.rs new file mode 100644 index 00000000000..227b98f0415 --- /dev/null +++ b/src/compiler/trim_paths.rs @@ -0,0 +1,198 @@ +//! Path prefix remapping for [RFC 3127] `trim-paths`. +//! +//! [RFC 3127]: https://rust-lang.github.io/rfcs/3127-trim-paths.html + +use std::ffi::OsString; +use std::path::Path; + +use cargo_util::ProcessBuilder; +use cargo_util_schemas::manifest::TomlTrimPaths; +use cargo_util_schemas::manifest::TomlTrimPathsValue; + +use super::BuildRunner; +use super::Unit; +use crate::util::errors::CargoResult; +use crate::util::hex; + +/// Like [`trim_paths_args`] but for rustdoc invocations. +pub(crate) fn trim_paths_args_rustdoc( + cmd: &mut ProcessBuilder, + build_runner: &BuildRunner<'_, '_>, + unit: &Unit, + trim_paths: &TomlTrimPaths, +) -> CargoResult<()> { + match trim_paths { + // rustdoc supports diagnostics trimming only. + TomlTrimPaths::Values(values) if !values.contains(&TomlTrimPathsValue::Diagnostics) => { + return Ok(()); + } + _ => {} + } + + for pair in trim_paths_remap(build_runner, unit) { + let mut arg = OsString::from("--remap-path-prefix="); + arg.push(pair); + cmd.arg(arg); + } + + Ok(()) +} + +/// 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 +pub(crate) fn trim_paths_args( + cmd: &mut ProcessBuilder, + build_runner: &BuildRunner<'_, '_>, + unit: &Unit, + trim_paths: &TomlTrimPaths, +) -> CargoResult<()> { + if trim_paths.is_none() { + return Ok(()); + } + + // feature gate was checked during manifest/config parsing. + cmd.arg(format!("--remap-path-scope={trim_paths}")); + + 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`. +/// +/// | Category | From | To | +/// |---------------------|----------------------------------------------|------------------------------------| +/// | Sysroot | `/lib/rustlib/src/rust` | `/rustc/` | +/// | Registry dep | `$CARGO_HOME/registry/src/` | `/cargo/registry/` | +/// | Git dep | `$CARGO_HOME/git/checkouts//` | `/cargo/git//` | +/// | Workspace | `` | `.` (workspace-relative) | +/// | Path dep outside ws | `` | `/cargo/path/-` | +/// | Vendored | `` (by file location) | workspace or path rules above | +/// | Build directory | `` | `/cargo/build-dir` | +/// +/// [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::new(); + remap.push({ + // See also `detect_sysroot_src_path()`. + let mut sysroot = build_runner.bcx.target_data.info(unit.kind).sysroot.clone(); + sysroot.push("lib"); + sysroot.push("rustlib"); + sysroot.push("src"); + sysroot.push("rust"); + sysroot + }); + remap.push("="); + remap.push("/rustc/"); + if let Some(commit_hash) = build_runner.bcx.rustc().commit_hash.as_ref() { + remap.push(commit_hash); + } else { + remap.push(build_runner.bcx.rustc().version.to_string()); + } + remap +} + +/// Path prefix remap rules for dependencies. +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::new(); + let source_id = unit.pkg.package_id().source_id(); + + if source_id.is_git() { + if let Some((from, rev)) = git_checkout(build_runner, pkg_root) { + const GIT_OID_LEN: usize = 7; // This matches MIN_ABBREV_LEN in git source + remap.push(from); + remap.push("=/cargo/git/"); + remap.push(hex::short_hash(source_id.canonical_url())); + remap.push("/"); + remap.push(&rev[..rev.len().min(GIT_OID_LEN)]); + return remap; + } + } else if source_id.is_registry() { + let registry_src = build_runner.bcx.gctx.registry_source_path(); + let registry_src = registry_src.as_path_unlocked(); + let from = pkg_root.parent().unwrap(); + if from.starts_with(registry_src) { + remap.push(from); + remap.push("=/cargo/registry/"); + remap.push(hex::short_hash(&source_id)); + return remap; + } + } + + // Handle path local dependencies and abnormal reg/git deps source location. + if pkg_root.strip_prefix(ws_root).is_ok() { + remap.push(ws_root); + remap.push("=."); // remap to relative rustc work dir explicitly + } else { + remap.push(pkg_root); + remap.push("=/cargo/path/"); + remap.push(unit.pkg.name()); + remap.push("-"); + remap.push(unit.pkg.version().to_string()); + } + remap +} + +/// Finds the checkout root and revision directory name of a git dependency. +/// +/// This is built under this layout: `$CARGO_HOME/git/checkouts/-[-shallow]/`. +/// +/// `None` when the package does not live under the global git checkouts directory, +/// for example a vendored git dependency. +fn git_checkout<'a>( + build_runner: &BuildRunner<'_, '_>, + pkg_root: &'a Path, +) -> Option<(&'a Path, &'a str)> { + let checkouts = build_runner.bcx.gctx.git_checkouts_path(); + let checkouts = checkouts.as_path_unlocked(); + let rel = pkg_root.strip_prefix(checkouts).ok()?; + let mut components = rel.components(); + let (_repo, rev) = (components.next()?, components.next()?); + let rev = rev.as_os_str().to_str()?; + let checkout_root = pkg_root.ancestors().nth(components.count())?; + Some((checkout_root, rev)) +} + +/// Remap all paths pointing to `build.build-dir`, +/// i.e., `[BUILD_DIR]/debug/deps/foo-[HASH].dwo` would be remapped to +/// `/cargo/build-dir/debug/deps/foo-[HASH].dwo` +/// (note the `/cargo/build-dir` prefix). +/// +/// This covers scenarios like: +/// +/// * Build script generated code. For example, a build script may call `file!` +/// macros, and the associated crate uses [`include!`] to include the expanded +/// [`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<'_, '_>) -> OsString { + let build_dir = build_runner.bcx.ws.build_dir(); + let mut remap = OsString::new(); + remap.push(build_dir.as_path_unlocked()); + remap.push("=/cargo/build-dir"); + remap +} diff --git a/tests/testsuite/profile_trim_paths.rs b/tests/testsuite/profile_trim_paths.rs index fe7e6c81794..e6a523dd222 100644 --- a/tests/testsuite/profile_trim_paths.rs +++ b/tests/testsuite/profile_trim_paths.rs @@ -227,7 +227,7 @@ fn registry_dependency() { p.cargo("run --verbose -Ztrim-paths") .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) .with_stdout_data(str![[r#" --[..]/bar-0.0.1/src/lib.rs +/cargo/registry/[..]/bar-0.0.1/src/lib.rs "#]]) // Omit the hash of Source URL .with_stderr_data(str![[r#" @@ -236,7 +236,7 @@ fn registry_dependency() { [DOWNLOADING] crates ... [DOWNLOADED] bar v0.0.1 (registry `dummy-registry`) [COMPILING] bar v0.0.1 -[RUNNING] `rustc [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/home/.cargo/registry/src= --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` +[RUNNING] `rustc [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/home/.cargo/registry/src/[..]=/cargo/registry/[..] --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` [COMPILING] foo v0.0.1 ([ROOT]/foo) [RUNNING] `rustc [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/foo=. --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s @@ -306,9 +306,9 @@ fn registry_dependency_with_build_script_codegen() { [DOWNLOADING] crates ... [DOWNLOADED] bar v0.0.1 (registry `dummy-registry`) [COMPILING] bar v0.0.1 -[RUNNING] `rustc --crate-name build_script_build [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/home/.cargo/registry/src= --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` +[RUNNING] `rustc --crate-name build_script_build [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/home/.cargo/registry/src/[..]=/cargo/registry/[..] --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` [RUNNING] `[ROOT]/foo/target/debug/build/bar-[HASH]/build-script-build` -[RUNNING] `rustc --crate-name bar [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/home/.cargo/registry/src= --remap-path-prefix=[ROOT]/foo/target=/cargo/build-dir --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] +[RUNNING] `rustc --crate-name bar [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/home/.cargo/registry/src/[..]=/cargo/registry/[..] --remap-path-prefix=[ROOT]/foo/target=/cargo/build-dir --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] [COMPILING] foo v0.0.1 ([ROOT]/foo) [RUNNING] `rustc --crate-name foo [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/foo=. --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s @@ -351,14 +351,14 @@ fn git_dependency() { p.cargo("run --verbose -Ztrim-paths") .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) .with_stdout_data(str![[r#" -bar-[..]/[..]/src/lib.rs +/cargo/git/[..]/src/lib.rs "#]]) // Omit the hash of Source URL and commit .with_stderr_data(str![[r#" [UPDATING] git repository `[ROOTURL]/bar` [LOCKING] 1 package to latest compatible version [COMPILING] bar v0.0.1 ([ROOTURL]/bar#[..]) -[RUNNING] `rustc [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/home/.cargo/git/checkouts= --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` +[RUNNING] `rustc [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/home/.cargo/git/checkouts/bar-[..]=/cargo/git/[..] --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` [COMPILING] foo v0.0.1 ([ROOT]/foo) [RUNNING] `rustc [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/foo=. --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s @@ -443,13 +443,13 @@ fn path_dependency_outside_workspace() { p.cargo("run --verbose -Ztrim-paths") .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) .with_stdout_data(str![[r#" -bar-0.0.1/src/lib.rs +/cargo/path/bar-0.0.1/src/lib.rs "#]]) .with_stderr_data(str![[r#" [LOCKING] 1 package to latest compatible version [COMPILING] bar v0.0.1 ([ROOT]/bar) -[RUNNING] `rustc [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/bar=bar-0.0.1 --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` +[RUNNING] `rustc [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/bar=/cargo/path/bar-0.0.1 --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` [COMPILING] foo v0.0.1 ([ROOT]/foo) [RUNNING] `rustc [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/foo=. --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s @@ -459,6 +459,225 @@ bar-0.0.1/src/lib.rs .run(); } +#[cargo_test] +fn vendored_dependencies() { + Package::new("bar", "0.0.1") + .file("Cargo.toml", &basic_manifest("bar", "0.0.1")) + .file("src/lib.rs", r#"pub fn f() { println!("{}", file!()); }"#) + .publish(); + let git_project = git::new("baz", |project| { + project + .file("Cargo.toml", &basic_manifest("baz", "0.0.1")) + .file("src/lib.rs", r#"pub fn f() { println!("{}", file!()); }"#) + }); + let url = git_project.url(); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + version = "0.0.1" + edition = "2015" + + [dependencies] + bar = "0.0.1" + baz = {{ git = "{url}" }} + + [profile.dev] + trim-paths = "object" + "# + ), + ) + .file("src/main.rs", "fn main() { bar::f(); baz::f(); }") + .build(); + + p.cargo("vendor --respect-source-config -Ztrim-paths") + .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) + .run(); + p.change_file( + ".cargo/config.toml", + &format!( + r#" + [source."git+{url}"] + git = "{url}" + replace-with = "vendored-sources" + + [source.crates-io] + replace-with = "vendored-sources" + + [source.vendored-sources] + directory = "vendor" + "# + ), + ); + + // Vendored deps within the workspace are remapped as local packages + p.cargo("run --verbose -Ztrim-paths") + .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) + .with_stderr_data( + str![[r#" +[COMPILING] bar v0.0.1 +[COMPILING] baz v0.0.1 ([ROOTURL]/baz#[..]) +[RUNNING] `rustc --crate-name bar [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/foo=. --remap-path-prefix=[ROOT]/foo/target=/cargo/build-dir --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` +[RUNNING] `rustc --crate-name baz [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/foo=. --remap-path-prefix=[ROOT]/foo/target=/cargo/build-dir --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` +[COMPILING] foo v0.0.1 ([ROOT]/foo) +[RUNNING] `rustc --crate-name foo [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/foo=. --remap-path-prefix=[ROOT]/foo/target=/cargo/build-dir --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s +[RUNNING] `target/debug/foo[EXE]` + +"#]] + .unordered(), + ) + .with_stdout_data(str![[r#" +./vendor/bar/src/lib.rs +./vendor/baz/src/lib.rs + +"#]]) + .run(); +} + +#[cargo_test] +fn vendored_dependencies_outside_workspace() { + Package::new("bar", "0.0.1") + .file("Cargo.toml", &basic_manifest("bar", "0.0.1")) + .file("src/lib.rs", r#"pub fn f() { println!("{}", file!()); }"#) + .publish(); + let git_project = git::new("baz", |project| { + project + .file("Cargo.toml", &basic_manifest("baz", "0.0.1")) + .file("src/lib.rs", r#"pub fn f() { println!("{}", file!()); }"#) + }); + let url = git_project.url(); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + version = "0.0.1" + edition = "2015" + + [dependencies] + bar = "0.0.1" + baz = {{ git = "{url}" }} + + [profile.dev] + trim-paths = "object" + "# + ), + ) + .file("src/main.rs", "fn main() { bar::f(); baz::f(); }") + .build(); + + p.cargo("vendor --respect-source-config -Ztrim-paths ../shared-vendor") + .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) + .run(); + p.change_file( + ".cargo/config.toml", + &format!( + r#" + [source."git+{url}"] + git = "{url}" + replace-with = "vendored-sources" + + [source.crates-io] + replace-with = "vendored-sources" + + [source.vendored-sources] + directory = '{}' + "#, + paths::root().join("shared-vendor").display() + ), + ); + + // Vendored deps outside the workspace are remapped as path dependencies + p.cargo("run --verbose -Ztrim-paths") + .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) + .with_stderr_data( + str![[r#" +[COMPILING] bar v0.0.1 +[COMPILING] baz v0.0.1 ([ROOTURL]/baz#[..]) +[RUNNING] `rustc --crate-name bar [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/shared-vendor/bar=/cargo/path/bar-0.0.1 --remap-path-prefix=[ROOT]/foo/target=/cargo/build-dir --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` +[RUNNING] `rustc --crate-name baz [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/shared-vendor/baz=/cargo/path/baz-0.0.1 --remap-path-prefix=[ROOT]/foo/target=/cargo/build-dir --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` +[COMPILING] foo v0.0.1 ([ROOT]/foo) +[RUNNING] `rustc --crate-name foo [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/foo=. --remap-path-prefix=[ROOT]/foo/target=/cargo/build-dir --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s +[RUNNING] `target/debug/foo[EXE]` + +"#]] + .unordered(), + ) + .with_stdout_data(str![[r#" +/cargo/path/bar-0.0.1/src/lib.rs +/cargo/path/baz-0.0.1/src/lib.rs + +"#]]) + .run(); +} + +#[cargo_test] +fn local_package_with_build_script_codegen() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + edition = "2015" + + [profile.dev] + trim-paths = "object" + "#, + ) + .file( + "build.rs", + r#" + fn main() { + let out_dir = std::env::var("OUT_DIR").unwrap(); + let dest = std::path::PathBuf::from(out_dir); + std::fs::write( + dest.join("bindings.rs"), + "pub fn my_file() -> &'static str { file!() }", + ) + .unwrap(); + } + "#, + ) + .file( + "src/main.rs", + r#" + include!(concat!(env!("OUT_DIR"), "/bindings.rs")); + fn main() { println!("{}", my_file()); } + "#, + ) + .build(); + + // The build-dir rule is passed last + // so paths should be remapped to `/cargo/build-dir` + p.cargo("run --verbose -Ztrim-paths") + .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) + .with_stdout_data(str![[r#" +/cargo/build-dir/debug/build/foo-[HASH]/out/bindings.rs + +"#]]) + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.1 ([ROOT]/foo) +[RUNNING] `rustc --crate-name build_script_build [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/foo=. --remap-path-prefix=[ROOT]/foo/target=/cargo/build-dir --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` +[RUNNING] `[ROOT]/foo/target/debug/build/foo-[HASH]/build-script-build` +[RUNNING] `rustc --crate-name foo [..]--remap-path-scope=object --remap-path-prefix=[ROOT]/foo=. --remap-path-prefix=[ROOT]/foo/target=/cargo/build-dir --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s +[RUNNING] `target/debug/foo[EXE]` + +"#]]) + .run(); +} + #[cargo_test] fn diagnostics_works() { Package::new("bar", "0.0.1") @@ -495,7 +714,7 @@ fn diagnostics_works() { ) .with_stderr_data(str![[r#" ... -[RUNNING] `[..] rustc [..]--remap-path-scope=diagnostics --remap-path-prefix=[ROOT]/home/.cargo/registry/src= --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` +[RUNNING] `[..] rustc [..]--remap-path-scope=diagnostics --remap-path-prefix=[ROOT]/home/.cargo/registry/src/[..]=/cargo/registry/[..] --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` [WARNING] unused variable: `unused` ... [RUNNING] `[..] rustc [..]--remap-path-scope=diagnostics --remap-path-prefix=[ROOT]/foo=. --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` @@ -670,7 +889,7 @@ fn object_works_helper(split_debuginfo: &str, run: impl Fn(&std::path::Path) -> [COMPILING] bar v0.0.1 [RUNNING] `rustc [..]-C split-debuginfo={split_debuginfo} [..]\ --remap-path-scope=object \ - --remap-path-prefix=[ROOT]/home/.cargo/registry/src= \ + --remap-path-prefix=[ROOT]/home/.cargo/registry/src/[..]=/cargo/registry/[..] \ --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] [COMPILING] foo v0.0.1 ([ROOT]/foo) [RUNNING] `rustc [..]-C split-debuginfo={split_debuginfo} [..]\ @@ -1091,10 +1310,10 @@ fn rustdoc_diagnostics_works() { .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) .with_stderr_data(str![[r#" ... -[RUNNING] `[..]rustc [..]--remap-path-scope=diagnostics --remap-path-prefix=[ROOT]/home/.cargo/registry/src= --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` +[RUNNING] `[..]rustc [..]--remap-path-scope=diagnostics --remap-path-prefix=[ROOT]/home/.cargo/registry/src/[..]=/cargo/registry/[..] --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]` ... [WARNING] unopened HTML tag `script` - --> -[..]/bar-0.0.1/src/lib.rs:2:17 + --> /cargo/registry/[HASH]/bar-0.0.1/src/lib.rs:2:17 ... "#]]) .run();