diff --git a/src/cargo/core/compiler/compile_kind.rs b/src/cargo/core/compiler/compile_kind.rs index c3c921d4146..9f6271ce0a9 100644 --- a/src/cargo/core/compiler/compile_kind.rs +++ b/src/cargo/core/compiler/compile_kind.rs @@ -182,14 +182,20 @@ impl CompileTarget { /// See [`CompileKind::fingerprint_hash`]. pub fn fingerprint_hash(&self) -> u64 { let mut hasher = StableHasher::new(); - self.name.hash(&mut hasher); - if self.name.ends_with(".json") { - // This may have some performance concerns, since it is called - // fairly often. If that ever seems worth fixing, consider - // embedding this in `CompileTarget`. - if let Ok(contents) = fs::read_to_string(self.name) { + match self + .name + .ends_with(".json") + .then(|| fs::read_to_string(self.name)) + { + Some(Ok(contents)) => { + // This may have some performance concerns, since it is called + // fairly often. If that ever seems worth fixing, consider + // embedding this in `CompileTarget`. contents.hash(&mut hasher); } + _ => { + self.name.hash(&mut hasher); + } } hasher.finish() } diff --git a/src/cargo/core/compiler/context/compilation_files.rs b/src/cargo/core/compiler/context/compilation_files.rs index 80a41cdaeff..f4d53c9240f 100644 --- a/src/cargo/core/compiler/context/compilation_files.rs +++ b/src/cargo/core/compiler/context/compilation_files.rs @@ -587,10 +587,12 @@ fn compute_metadata( unit.mode.hash(&mut hasher); cx.lto[unit].hash(&mut hasher); - // Artifacts compiled for the host should have a different metadata - // piece than those compiled for the target, so make sure we throw in - // the unit's `kind` as well - unit.kind.hash(&mut hasher); + // Artifacts compiled for the host should have a different + // metadata piece than those compiled for the target, so make sure + // we throw in the unit's `kind` as well. Use `fingerprint_hash` + // so that the StableHash doesn't change based on the pathnames + // of the custom target JSON spec files. + unit.kind.fingerprint_hash().hash(&mut hasher); // Finally throw in the target name/kind. This ensures that concurrent // compiles of targets in the same crate don't collide. diff --git a/tests/testsuite/custom_target.rs b/tests/testsuite/custom_target.rs index 8b4c9ac3d43..07c41b9a5c7 100644 --- a/tests/testsuite/custom_target.rs +++ b/tests/testsuite/custom_target.rs @@ -234,3 +234,42 @@ fn changing_spec_relearns_crate_types() { ) .run(); } + +#[cargo_test] +fn custom_target_ignores_filepath() { + // Changing the path of the .json file will not trigger a rebuild. + if !is_nightly() { + // Requires features no_core, lang_items + return; + } + let p = project() + .file( + "src/lib.rs", + &" + __MINIMAL_LIB__ + + pub fn foo() -> u32 { + 42 + } + " + .replace("__MINIMAL_LIB__", MINIMAL_LIB), + ) + .file("b/custom-target.json", SIMPLE_SPEC) + .file("a/custom-target.json", SIMPLE_SPEC) + .build(); + + // Should build the library the first time. + p.cargo("build --lib --target a/custom-target.json") + .with_stderr( + "\ +[..]Compiling foo v0.0.1 ([..]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +", + ) + .run(); + + // But not the second time, even though the path to the custom target is dfferent. + p.cargo("build --lib --target b/custom-target.json") + .with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]") + .run(); +}