Skip to content

Commit

Permalink
Fix avoiding a rebuild when moving around a workspace
Browse files Browse the repository at this point in the history
There's a case where Cargo will recompile a project even if the fingerprint
looks like it's fresh, when some output files are missing. This was intended to
cover the case where an output file was deleted manually or otherwise messed
with. The check here was a bit too eager, however. It checked not only the
actual output destination of the compiler but *also* the location that we hard
link the output file up to.

Due to recent changes in rust-lang#5460 we don't always create the hard links for path
dependencies in the top-level dir, and this meant that if the library were
compiled and then tested later on the test may recompile the original library by
accident.

The fix in this commit is to cease looking for the hardlink if it exists or not.
This way we only check for the presence of the output file itself and only
recompile if that file is missing. The reason for this is that we
unconditionally relink files into place whether it's fresh or not, so we'll
always recreate the hard link anyway if it's missing.

cc rust-lang/rust#51717
  • Loading branch information
alexcrichton committed Jun 29, 2018
1 parent 9e4845e commit 4be5a44
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 3 deletions.
7 changes: 4 additions & 3 deletions src/cargo/core/compiler/fingerprint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,10 @@ pub fn prepare_target<'a, 'cfg>(
if output.flavor == FileFlavor::DebugInfo {
continue;
}
missing_outputs |= !output.path.exists();
if let Some(ref link_dst) = output.hardlink {
missing_outputs |= !link_dst.exists();
if !output.path.exists() {
info!("missing output path {:?}", output.path);
missing_outputs = true;
break
}
}
}
Expand Down
38 changes: 38 additions & 0 deletions tests/testsuite/freshness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1243,3 +1243,41 @@ fn dont_rebuild_based_on_plugins() {
execs().with_status(0).with_stderr("[FINISHED] [..]\n"),
);
}

#[test]
fn reuse_workspace_lib() {
let p = project("p")
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.1"
[workspace]
[dependencies]
bar = { path = 'bar' }
"#,
)
.file("src/lib.rs", "")
.file(
"bar/Cargo.toml",
r#"
[package]
name = "bar"
version = "0.1.1"
"#,
)
.file("bar/src/lib.rs", "")
.build();

assert_that(p.cargo("build"), execs().with_status(0));
assert_that(
p.cargo("test -p bar -v --no-run"),
execs().with_status(0).with_stderr("\
[COMPILING] bar v0.1.1 ([..])
[RUNNING] `rustc[..] --test [..]`
[FINISHED] [..]
"));
}

0 comments on commit 4be5a44

Please sign in to comment.