Skip to content

Commit a74a8d0

Browse files
committed
Auto merge of #11122 - weihanglo:issue-11101, r=epage
Unlink old final artifacts before compilation
2 parents 6a88dd8 + b47cacb commit a74a8d0

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ features = [
9999
[dev-dependencies]
100100
cargo-test-macro = { path = "crates/cargo-test-macro" }
101101
cargo-test-support = { path = "crates/cargo-test-support" }
102+
same-file = "1.0.6"
102103
snapbox = { version = "0.3.0", features = ["diff", "path"] }
103104

104105
[build-dependencies]

src/cargo/core/compiler/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,19 @@ fn rustc(cx: &mut Context<'_, '_>, unit: &Unit, exec: &Arc<dyn Executor>) -> Car
305305
paths::remove_file(&dst)?;
306306
}
307307
}
308+
309+
// Some linkers do not remove the executable, but truncate and modify it.
310+
// That results in the old hard-link being modified even after renamed.
311+
// We delete the old artifact here to prevent this behavior from confusing users.
312+
// See rust-lang/cargo#8348.
313+
if output.hardlink.is_some() && output.path.exists() {
314+
_ = paths::remove_file(&output.path).map_err(|e| {
315+
log::debug!(
316+
"failed to delete previous output file `{:?}`: {e:?}",
317+
output.path
318+
);
319+
});
320+
}
308321
}
309322

310323
fn verbose_if_simple_exit_code(err: Error) -> Error {

tests/testsuite/build.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6247,3 +6247,32 @@ fn primary_package_env_var() {
62476247

62486248
foo.cargo("test").run();
62496249
}
6250+
6251+
#[cargo_test]
6252+
fn renamed_uplifted_artifact_remains_unmodified_after_rebuild() {
6253+
let p = project()
6254+
.file(
6255+
"Cargo.toml",
6256+
r#"
6257+
[package]
6258+
name = "foo"
6259+
authors = []
6260+
version = "0.0.0"
6261+
"#,
6262+
)
6263+
.file("src/main.rs", "fn main() {}")
6264+
.build();
6265+
6266+
p.cargo("build").run();
6267+
6268+
let bin = p.bin("foo");
6269+
let renamed_bin = p.bin("foo-renamed");
6270+
6271+
fs::rename(&bin, &renamed_bin).unwrap();
6272+
6273+
p.change_file("src/main.rs", "fn main() { eprintln!(\"hello, world\"); }");
6274+
p.cargo("build").run();
6275+
6276+
let not_the_same = !same_file::is_same_file(bin, renamed_bin).unwrap();
6277+
assert!(not_the_same, "renamed uplifted artifact must be unmodified");
6278+
}

0 commit comments

Comments
 (0)