super::compile(&mut self, &mut queue, &mut plan, unit, exec, force_rebuild)?;
}
+ // Now that we've got the full job queue and we've done all our
+ // fingerprint analysis to determine what to run, bust all the memoized
+ // fingerprint hashes to ensure that during the build they all get the
+ // most up-to-date values. In theory we only need to bust hashes that
+ // transitively depend on a dirty build script, but it shouldn't matter
+ // that much for performance anyway.
+ for fingerprint in self.fingerprints.values() {
+ fingerprint.clear_memoized();
+ }
+
// Now that we've figured out everything that we're going to do, do it!
queue.execute(&mut self, &mut plan)?;
// hobble along if it happens to return `Some`.
if let Some(new_local) = (gen_local)(&deps, None)? {
*fingerprint.local.lock().unwrap() = new_local;
- *fingerprint.memoized_hash.lock().unwrap() = None;
}
write_fingerprint(&loc, &fingerprint)
}
}
+ /// For performance reasons fingerprints will memoize their own hash, but
+ /// there's also internal mutability with its `local` field which can
+ /// change, for example with build scripts, during a build.
+ ///
+ /// This method can be used to bust all memoized hashes just before a build
+ /// to ensure that after a build completes everything is up-to-date.
+ pub fn clear_memoized(&self) {
+ *self.memoized_hash.lock().unwrap() = None;
+ }
+
fn hash(&self) -> u64 {
if let Some(s) = *self.memoized_hash.lock().unwrap() {
return s;
.with_stderr("[FINISHED] [..]")
.run();
}
+
+#[cargo_test]
+fn rerun_if_changes() {
+ let p = project()
+ .file(
+ "build.rs",
+ r#"
+ fn main() {
+ println!("cargo:rerun-if-env-changed=FOO");
+ if std::env::var("FOO").is_ok() {
+ println!("cargo:rerun-if-env-changed=BAR");
+ }
+ }
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ p.cargo("build").run();
+ p.cargo("build").with_stderr("[FINISHED] [..]").run();
+
+ p.cargo("build -v")
+ .env("FOO", "1")
+ .with_stderr(
+ "\
+[COMPILING] foo [..]
+[RUNNING] `[..]build-script-build`
+[RUNNING] `rustc [..]
+[FINISHED] [..]
+",
+ )
+ .run();
+ p.cargo("build")
+ .env("FOO", "1")
+ .with_stderr("[FINISHED] [..]")
+ .run();
+
+ p.cargo("build -v")
+ .env("FOO", "1")
+ .env("BAR", "1")
+ .with_stderr(
+ "\
+[COMPILING] foo [..]
+[RUNNING] `[..]build-script-build`
+[RUNNING] `rustc [..]
+[FINISHED] [..]
+",
+ )
+ .run();
+ p.cargo("build")
+ .env("FOO", "1")
+ .env("BAR", "1")
+ .with_stderr("[FINISHED] [..]")
+ .run();
+
+ p.cargo("build -v")
+ .env("BAR", "2")
+ .with_stderr(
+ "\
+[COMPILING] foo [..]
+[RUNNING] `[..]build-script-build`
+[RUNNING] `rustc [..]
+[FINISHED] [..]
+",
+ )
+ .run();
+ p.cargo("build")
+ .env("BAR", "2")
+ .with_stderr("[FINISHED] [..]")
+ .run();
+}