Skip to content

Commit 61fa024

Browse files
committed
Auto merge of #4739 - kennytm:backport-4672, r=matklad
[beta] When uplifting directories, symlink them instead of hard-link them. Backport of #4672 to 1.22 (cargo 0.23) The current stable RC (cee38cd) contains #4616 *but not* #4672. Without the latter it is known to cause #4671 on APFS (enabled by default on macOS 10.13 "High Sierra"). The issue was found by kpy3 on https://internals.rust-lang.org/t/rust-1-22-0-prerelease-testing/6282/2.
2 parents cee38cd + 2c6a0fe commit 61fa024

File tree

3 files changed

+31
-12
lines changed

3 files changed

+31
-12
lines changed

src/cargo/ops/cargo_rustc/mod.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -533,15 +533,28 @@ fn link_targets<'a, 'cfg>(cx: &mut Context<'a, 'cfg>,
533533
format!("failed to remove: {}", dst.display())
534534
})?;
535535
}
536-
fs::hard_link(src, dst)
537-
.or_else(|err| {
538-
debug!("hard link failed {}. falling back to fs::copy", err);
539-
fs::copy(src, dst).map(|_| ())
540-
})
541-
.chain_err(|| {
536+
537+
let link_result = if src.is_dir() {
538+
#[cfg(unix)]
539+
use std::os::unix::fs::symlink;
540+
#[cfg(target_os = "redox")]
541+
use std::os::redox::fs::symlink;
542+
#[cfg(windows)]
543+
use std::os::windows::fs::symlink_dir as symlink;
544+
545+
symlink(src, dst)
546+
} else {
547+
fs::hard_link(src, dst)
548+
};
549+
link_result
550+
.or_else(|err| {
551+
debug!("link failed {}. falling back to fs::copy", err);
552+
fs::copy(src, dst).map(|_| ())
553+
})
554+
.chain_err(|| {
542555
format!("failed to link or copy `{}` to `{}`",
543556
src.display(), dst.display())
544-
})?;
557+
})?;
545558
}
546559

547560
if json_messages {

tests/build.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3899,6 +3899,13 @@ fn uplift_dsym_of_bin_on_mac() {
38993899
);
39003900
assert_that(&p.bin("foo.dSYM"), existing_dir());
39013901
assert_that(&p.bin("b.dSYM"), existing_dir());
3902+
assert!(
3903+
p.bin("b.dSYM")
3904+
.symlink_metadata()
3905+
.expect("read metadata from b.dSYM")
3906+
.file_type()
3907+
.is_symlink()
3908+
);
39023909
assert_that(&p.bin("c.dSYM"), is_not(existing_dir()));
39033910
assert_that(&p.bin("d.dSYM"), is_not(existing_dir()));
39043911
}

tests/cargotest/support/paths.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,14 @@ impl CargoPathExt for Path {
8181
}
8282

8383
for file in t!(fs::read_dir(self)) {
84-
let file = t!(file).path();
85-
86-
if file.is_dir() {
87-
file.rm_rf();
84+
let file = t!(file);
85+
if file.file_type().map(|m| m.is_dir()).unwrap_or(false) {
86+
file.path().rm_rf();
8887
} else {
8988
// On windows we can't remove a readonly file, and git will
9089
// often clone files as readonly. As a result, we have some
9190
// special logic to remove readonly files on windows.
92-
do_op(&file, "remove file", |p| fs::remove_file(p));
91+
do_op(&file.path(), "remove file", |p| fs::remove_file(p));
9392
}
9493
}
9594
do_op(self, "remove dir", |p| fs::remove_dir(p));

0 commit comments

Comments
 (0)