From dba34d4552f68eca3d7108531f0fe5007ddb4f8b Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Tue, 20 Aug 2024 17:49:12 -0400 Subject: [PATCH 1/2] test: show runtime-dep and build-dep collides See rust-lang/cargo 14253 --- tests/testsuite/rustflags.rs | 71 ++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/tests/testsuite/rustflags.rs b/tests/testsuite/rustflags.rs index 81ce4c3aef3..7492d4061f6 100644 --- a/tests/testsuite/rustflags.rs +++ b/tests/testsuite/rustflags.rs @@ -1642,3 +1642,74 @@ fn target_applies_to_host_rustdocflags_works() { ) .run(); } + +#[cargo_test] +fn host_config_shared_build_dep() { + // rust-lang/cargo#14253 + Package::new("cc", "1.0.0").publish(); + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "bootstrap" + edition = "2021" + + [dependencies] + cc = "1.0.0" + + [build-dependencies] + cc = "1.0.0" + + [profile.dev] + debug = 0 + "#, + ) + .file("src/lib.rs", "") + .file("build.rs", "fn main() {}") + .file( + ".cargo/config.toml", + " + target-applies-to-host=false + + [host] + rustflags = ['--cfg', 'from_host'] + + [build] + rustflags = ['--cfg', 'from_target'] + ", + ) + .build(); + + p.cargo("build -v") + .masquerade_as_nightly_cargo(&["target-applies-to-host"]) + .arg("-Ztarget-applies-to-host") + .arg("-Zhost-config") + // Sometimes it compiles. Not deterministic... + .with_stderr_data(str![[r#" +[UPDATING] `dummy-registry` index +[LOCKING] 2 packages to latest compatible versions +[DOWNLOADING] crates ... +[DOWNLOADED] cc v1.0.0 (registry `dummy-registry`) +[WARNING] output filename collision. +The lib target `cc` in package `cc v1.0.0` has the same output filename as the lib target `cc` in package `cc v1.0.0`. +Colliding filename is: [ROOT]/foo/target/debug/deps/libcc-[HASH].rlib +The targets should have unique names. +Consider changing their names to be unique or compiling them separately. +This may become a hard error in the future; see . +[WARNING] output filename collision. +The lib target `cc` in package `cc v1.0.0` has the same output filename as the lib target `cc` in package `cc v1.0.0`. +Colliding filename is: [ROOT]/foo/target/debug/deps/libcc-[HASH].rmeta +The targets should have unique names. +Consider changing their names to be unique or compiling them separately. +This may become a hard error in the future; see . +[COMPILING] cc v1.0.0 +[RUNNING] `rustc --crate-name cc [..]--cfg from_host[..]` +[RUNNING] `rustc --crate-name cc [..]--cfg from_target[..]` +[ERROR] failed to build archive: No such file or directory + +[ERROR] could not compile `cc` (lib) due to 1 previous error + +"#]]) + .run(); +} From d12c7161408f37a4a9c875d95f81be2fe5c4d9da Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Tue, 20 Aug 2024 20:13:38 -0400 Subject: [PATCH 2/2] fix: `-Cmetadata` includes whether extra rustflags is same as host `-Ztarget-applies-to-host --config target-applies-to-host=false` make it possible to build two units for the same output directory with different rustflags (one with artifact/target rustflags, one with none/host rust flags). Those flags aren't included in the `-Cmetadata` hash which is used to disambiguate different versions of crates, resulting in a conflict. The actual error being produced appears to be the result of two invocations of `rustc` racing and clobbering each other. While we don't hash RUSTFLAGS because it may contain absolute paths that hurts reproducibility, we track whether a unit's RUSTFLAGS is from host config, so that we can generate a different metadata hash for runtime and compile-time units. --- .../build_runner/compilation_files.rs | 20 +++++++++++++ tests/testsuite/rustflags.rs | 30 +++++++------------ 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/cargo/core/compiler/build_runner/compilation_files.rs b/src/cargo/core/compiler/build_runner/compilation_files.rs index cad6f0db773..667cf0379e0 100644 --- a/src/cargo/core/compiler/build_runner/compilation_files.rs +++ b/src/cargo/core/compiler/build_runner/compilation_files.rs @@ -649,6 +649,26 @@ fn compute_metadata( // with user dependencies. unit.is_std.hash(&mut hasher); + // While we don't hash RUSTFLAGS because it may contain absolute paths that + // hurts reproducibility, we track whether a unit's RUSTFLAGS is from host + // config, so that we can generate a different metadata hash for runtime + // and compile-time units. + // + // HACK: This is a temporary hack for fixing rust-lang/cargo#14253 + // Need to find a long-term solution to replace this fragile workaround. + // See https://github.com/rust-lang/cargo/pull/14432#discussion_r1725065350 + if unit.kind.is_host() && !bcx.gctx.target_applies_to_host().unwrap_or_default() { + let host_info = bcx.target_data.info(CompileKind::Host); + let target_configs_are_different = unit.rustflags != host_info.rustflags + || unit.rustdocflags != host_info.rustdocflags + || bcx + .target_data + .target_config(CompileKind::Host) + .links_overrides + != unit.links_overrides; + target_configs_are_different.hash(&mut hasher); + } + MetaInfo { meta_hash: Metadata(hasher.finish()), use_extra_filename: should_use_metadata(bcx, unit), diff --git a/tests/testsuite/rustflags.rs b/tests/testsuite/rustflags.rs index 7492d4061f6..5d078b5bebc 100644 --- a/tests/testsuite/rustflags.rs +++ b/tests/testsuite/rustflags.rs @@ -1685,31 +1685,23 @@ fn host_config_shared_build_dep() { .masquerade_as_nightly_cargo(&["target-applies-to-host"]) .arg("-Ztarget-applies-to-host") .arg("-Zhost-config") - // Sometimes it compiles. Not deterministic... - .with_stderr_data(str![[r#" + .with_stderr_data( + str![[r#" [UPDATING] `dummy-registry` index [LOCKING] 2 packages to latest compatible versions [DOWNLOADING] crates ... [DOWNLOADED] cc v1.0.0 (registry `dummy-registry`) -[WARNING] output filename collision. -The lib target `cc` in package `cc v1.0.0` has the same output filename as the lib target `cc` in package `cc v1.0.0`. -Colliding filename is: [ROOT]/foo/target/debug/deps/libcc-[HASH].rlib -The targets should have unique names. -Consider changing their names to be unique or compiling them separately. -This may become a hard error in the future; see . -[WARNING] output filename collision. -The lib target `cc` in package `cc v1.0.0` has the same output filename as the lib target `cc` in package `cc v1.0.0`. -Colliding filename is: [ROOT]/foo/target/debug/deps/libcc-[HASH].rmeta -The targets should have unique names. -Consider changing their names to be unique or compiling them separately. -This may become a hard error in the future; see . [COMPILING] cc v1.0.0 [RUNNING] `rustc --crate-name cc [..]--cfg from_host[..]` [RUNNING] `rustc --crate-name cc [..]--cfg from_target[..]` -[ERROR] failed to build archive: No such file or directory - -[ERROR] could not compile `cc` (lib) due to 1 previous error - -"#]]) +[COMPILING] bootstrap v0.0.0 ([ROOT]/foo) +[RUNNING] `rustc --crate-name build_script_build [..]--cfg from_host[..]` +[RUNNING] `[ROOT]/foo/target/debug/build/bootstrap-[HASH]/build-script-build` +[RUNNING] `rustc --crate-name bootstrap[..]--cfg from_target[..]` +[FINISHED] `dev` profile [unoptimized] target(s) in [ELAPSED]s + +"#]] + .unordered(), + ) .run(); }