Avoid fingerprint busting during builds (#4244)
* Avoid fingerprint busting during builds * delete `.fingerprint/package-hash` instead of modifying source code --------- Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
This commit is contained in:
1 parent
f40f7a5aeb
commit
e477e0b485
2 files changed
+40
-14
No files matched your search
@@ -3802,7 +3802,7 @@ impl BuildRequest {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// update the mtime of the "main" file to bust the fingerprint, forcing rustc to recompile it.
|
||||
/// Blow away the fingerprint for this package, forcing rustc to recompile it.
|
||||
///
|
||||
/// This prevents rustc from using the cached version of the binary, which can cause issues
|
||||
/// with our hotpatching setup since it uses linker interception.
|
||||
@@ -3812,13 +3812,29 @@ impl BuildRequest {
|
||||
///
|
||||
/// This might stop working if/when cargo stabilizes contents-based fingerprinting.
|
||||
fn bust_fingerprint(&self, ctx: &BuildContext) -> Result<()> {
|
||||
if !matches!(ctx.mode, BuildMode::Thin { .. }) {
|
||||
std::fs::File::open(&self.crate_target.src_path)?.set_modified(SystemTime::now())?;
|
||||
if matches!(ctx.mode, BuildMode::Fat) {
|
||||
// `dx` compiles everything with `--target` which ends up with a structure like:
|
||||
// target/<triple>/<profile>/.fingerprint/<package_name>-<hash>
|
||||
//
|
||||
// normally you can't rely on this structure (ie with `cargo build`) but the explicit
|
||||
// target arg guarantees this will work.
|
||||
let fingerprint_dir = self
|
||||
.target_dir
|
||||
.join(self.triple.to_string())
|
||||
.join(&self.profile)
|
||||
.join(".fingerprint");
|
||||
|
||||
// read and write the file to update the mtime
|
||||
if cfg!(target_os = "windows") {
|
||||
let contents = std::fs::read_to_string(&self.crate_target.src_path)?;
|
||||
_ = std::fs::write(&self.crate_target.src_path, contents);
|
||||
// split at the last `-` used to separate the hash from the name
|
||||
// This causes to more aggressively bust hashes for all combinations of features
|
||||
// and fingerprints for this package since we're just ignoring the hash
|
||||
for entry in std::fs::read_dir(&fingerprint_dir)?.flatten() {
|
||||
if let Some(fname) = entry.file_name().to_str() {
|
||||
if let Some((name, _)) = fname.rsplit_once('-') {
|
||||
if name == self.package().name {
|
||||
_ = std::fs::remove_dir_all(entry.path());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -54,13 +54,23 @@ pub async fn run_rustc() {
|
||||
link_args: Default::default(),
|
||||
};
|
||||
|
||||
std::fs::create_dir_all(var_file.parent().expect("Failed to get parent dir"))
|
||||
.expect("Failed to create parent dir");
|
||||
std::fs::write(
|
||||
&var_file,
|
||||
serde_json::to_string(&rustc_args).expect("Failed to serialize rustc args"),
|
||||
)
|
||||
.expect("Failed to write rustc args to file");
|
||||
// Another terrible hack to avoid caching non-sensical args when
|
||||
// a build is completely fresh (rustc is invoked with --crate-name ___)
|
||||
if rustc_args
|
||||
.args
|
||||
.iter()
|
||||
.skip_while(|arg| *arg != "--crate-name")
|
||||
.nth(1)
|
||||
.is_some_and(|name| name != "___")
|
||||
{
|
||||
std::fs::create_dir_all(var_file.parent().expect("Failed to get parent dir"))
|
||||
.expect("Failed to create parent dir");
|
||||
std::fs::write(
|
||||
&var_file,
|
||||
serde_json::to_string(&rustc_args).expect("Failed to serialize rustc args"),
|
||||
)
|
||||
.expect("Failed to write rustc args to file");
|
||||
}
|
||||
|
||||
// Run the actual rustc command
|
||||
// We want all stdout/stderr to be inherited, so the running process can see the output
|
||||
|
||||
Reference in new issue
Block a user