Skip to content

Commit

Permalink
Handle rerun-if-changed directives in dependencies
Browse files Browse the repository at this point in the history
There was a failure mode of the handling of the rerun-if-changed directive where
it would rerun the build script twice before hitting a steady state of actually
processing the directives. The order of events that led to this were:

1. A project was built from a clean directory. Cargo recorded a fingerprint
   indicating this (for the build script), but the fingerprint indicated that
   the build script was a normal build script (no manually specified inputs)
   because Cargo had no prior knowledge.
2. A project was then rebuilt from the same directory. Cargo's new fingerprint
   for the build script now indicates that there is a custom list of
   dependencies, but the previous fingerprint indicates there wasn't, so the
   mismatch causes another rebuild.
3. All future rebuilds will agree that there are custom lists both before and
   after, so the directives are processed as one would expect.

This commit does a bit of refactoring in the fingerprint module to fix this
situation. The recorded fingerprint in step (1) is now recorded as a "custom
dependencies are specified" fingerprint if, after the build script is run,
custom dependencies were specified.

Closes rust-lang#2267
  • Loading branch information
alexcrichton committed Jan 13, 2016
1 parent 9b0ed1d commit 7dcedd8
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 146 deletions.
9 changes: 5 additions & 4 deletions src/cargo/ops/cargo_rustc/custom_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,11 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>)
// Check to see if the build script as already run, and if it has keep
// track of whether it has told us about some explicit dependencies
let prev_output = BuildOutput::parse_file(&output_file, &pkg_name).ok();
if let Some(ref prev) = prev_output {
let val = (output_file.clone(), prev.rerun_if_changed.clone());
cx.build_explicit_deps.insert(*unit, val);
}
let rerun_if_changed = match prev_output {
Some(ref prev) => prev.rerun_if_changed.clone(),
None => Vec::new(),
};
cx.build_explicit_deps.insert(*unit, (output_file.clone(), rerun_if_changed));

try!(fs::create_dir_all(&cx.layout(unit.pkg, Kind::Host).build(unit.pkg)));
try!(fs::create_dir_all(&cx.layout(unit.pkg, unit.kind).build(unit.pkg)));
Expand Down
Loading

0 comments on commit 7dcedd8

Please sign in to comment.