Skip to content

Use fingerprint_hash when computing fingerprints for custom targets #10746

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 20, 2022
Merged
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
18 changes: 12 additions & 6 deletions src/cargo/core/compiler/compile_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down
10 changes: 6 additions & 4 deletions src/cargo/core/compiler/context/compilation_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
39 changes: 39 additions & 0 deletions tests/testsuite/custom_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}