Auto merge of #11122 - weihanglo:issue-11101, r=epage

Unlink old final artifacts before compilation
This commit is contained in:
bors 2022-09-21 16:43:29 +00:00
commit a74a8d0456
3 changed files with 43 additions and 0 deletions

View File

@ -99,6 +99,7 @@ features = [
[dev-dependencies]
cargo-test-macro = { path = "crates/cargo-test-macro" }
cargo-test-support = { path = "crates/cargo-test-support" }
same-file = "1.0.6"
snapbox = { version = "0.3.0", features = ["diff", "path"] }
[build-dependencies]

View File

@ -305,6 +305,19 @@ fn rustc(cx: &mut Context<'_, '_>, unit: &Unit, exec: &Arc<dyn Executor>) -> Car
paths::remove_file(&dst)?;
}
}
// Some linkers do not remove the executable, but truncate and modify it.
// That results in the old hard-link being modified even after renamed.
// We delete the old artifact here to prevent this behavior from confusing users.
// See rust-lang/cargo#8348.
if output.hardlink.is_some() && output.path.exists() {
_ = paths::remove_file(&output.path).map_err(|e| {
log::debug!(
"failed to delete previous output file `{:?}`: {e:?}",
output.path
);
});
}
}
fn verbose_if_simple_exit_code(err: Error) -> Error {

View File

@ -6247,3 +6247,32 @@ fn primary_package_env_var() {
foo.cargo("test").run();
}
#[cargo_test]
fn renamed_uplifted_artifact_remains_unmodified_after_rebuild() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
authors = []
version = "0.0.0"
"#,
)
.file("src/main.rs", "fn main() {}")
.build();
p.cargo("build").run();
let bin = p.bin("foo");
let renamed_bin = p.bin("foo-renamed");
fs::rename(&bin, &renamed_bin).unwrap();
p.change_file("src/main.rs", "fn main() { eprintln!(\"hello, world\"); }");
p.cargo("build").run();
let not_the_same = !same_file::is_same_file(bin, renamed_bin).unwrap();
assert!(not_the_same, "renamed uplifted artifact must be unmodified");
}