Skip to content

Commit f573db4

Browse files
committed
Auto merge of #39518 - alexcrichton:update-cargo, r=arielb1
rustbuild: Use copies instead of hard links The original motivation for hard links was to speed up the various stages of rustbuild, but in the end this is causing problems on Windows (#39504). This commit tweaks the build system to use copies instead of hard links unconditionally to ensure that the files accessed by Windows are always disjoint. Locally this added .3s to a noop build, so it shouldn't be too much of a regression hopefully! Closes #39504
2 parents 5aaa606 + 6f43149 commit f573db4

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

src/bootstrap/util.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ use std::path::{Path, PathBuf};
2020
use std::process::Command;
2121
use std::time::Instant;
2222

23+
use filetime::{self, FileTime};
24+
2325
/// Returns the `name` as the filename of a static library for `target`.
2426
pub fn staticlib(name: &str, target: &str) -> String {
2527
if target.contains("windows") {
@@ -38,12 +40,18 @@ pub fn copy(src: &Path, dst: &Path) {
3840

3941
// Attempt to "easy copy" by creating a hard link (symlinks don't work on
4042
// windows), but if that fails just fall back to a slow `copy` operation.
41-
let res = fs::hard_link(src, dst);
42-
let res = res.or_else(|_| fs::copy(src, dst).map(|_| ()));
43+
// let res = fs::hard_link(src, dst);
44+
let res = fs::copy(src, dst);
4345
if let Err(e) = res {
4446
panic!("failed to copy `{}` to `{}`: {}", src.display(),
4547
dst.display(), e)
4648
}
49+
let metadata = t!(src.metadata());
50+
t!(fs::set_permissions(dst, metadata.permissions()));
51+
let atime = FileTime::from_last_access_time(&metadata);
52+
let mtime = FileTime::from_last_modification_time(&metadata);
53+
t!(filetime::set_file_times(dst, atime, mtime));
54+
4755
}
4856

4957
/// Copies the `src` directory recursively to `dst`. Both are assumed to exist

src/librustc_metadata/locator.rs

+28
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,34 @@ impl<'a> Context<'a> {
639639
lib.display()));
640640
continue;
641641
}
642+
643+
// Ok so at this point we've determined that `(lib, kind)` above is
644+
// a candidate crate to load, and that `slot` is either none (this
645+
// is the first crate of its kind) or if some the previous path has
646+
// the exact same hash (e.g. it's the exact same crate).
647+
//
648+
// In principle these two candidate crates are exactly the same so
649+
// we can choose either of them to link. As a stupidly gross hack,
650+
// however, we favor crate in the sysroot.
651+
//
652+
// You can find more info in rust-lang/rust#39518 and various linked
653+
// issues, but the general gist is that during testing libstd the
654+
// compilers has two candidates to choose from: one in the sysroot
655+
// and one in the deps folder. These two crates are the exact same
656+
// crate but if the compiler chooses the one in the deps folder
657+
// it'll cause spurious errors on Windows.
658+
//
659+
// As a result, we favor the sysroot crate here. Note that the
660+
// candidates are all canonicalized, so we canonicalize the sysroot
661+
// as well.
662+
if let Some((ref prev, _)) = ret {
663+
let sysroot = self.sess.sysroot();
664+
let sysroot = sysroot.canonicalize()
665+
.unwrap_or(sysroot.to_path_buf());
666+
if prev.starts_with(&sysroot) {
667+
continue
668+
}
669+
}
642670
*slot = Some((hash, metadata));
643671
ret = Some((lib, kind));
644672
}

src/stage0.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@
1313
# released on `$date`
1414

1515
rustc: beta-2017-02-01
16-
cargo: bfee18f73287687c543bda8c35e4e33808792715
16+
cargo: 407edef22e894266eb562618cba5ca9757051946

0 commit comments

Comments
 (0)