Make "Assemble stage1 compiler" orders of magnitude faster
This used to take upwards of 5 seconds for me locally. I found that the culprit was copying the downloaded LLVM shared object: ``` [22:28:03] Install "/home/jnelson/rust-lang/rust/build/x86_64-unknown-linux-gnu/ci-llvm/lib/libLLVM-14-rust-1.62.0-nightly.so" to "/home/jnelson/rust-lang/rust/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/lib/libLLVM-14-rust-1.62.0-nightly.so" [22:28:09] c Sysroot { compiler: Compiler { stage: 1, host: x86_64-unknown-linux-gnu(x86_64-unknown-linux-gnu) } } ``` It turned out that `install()` used full copies unconditionally. Change it to use `copy()` internally, which uses hard links instead when available. Note that this has a change in behavior: Installing a file will also change permissions on the source, not just the destination, if hard links are used. To avoid changing the behavior on symlinks for existing code, I introduce a new function `copy_internal` which only dereferences symlinks when told to do so.
This commit is contained in:
parent
b9eedea4b0
commit
057eab7ae9
2 changed files with 20 additions and 18 deletions
|
@ -1873,7 +1873,6 @@ fn add_env(builder: &Builder<'_>, cmd: &mut Command, target: TargetSelection) {
|
|||
|
||||
/// Maybe add LLVM object files to the given destination lib-dir. Allows either static or dynamic linking.
|
||||
///
|
||||
|
||||
/// Returns whether the files were actually copied.
|
||||
fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir: &Path) -> bool {
|
||||
if let Some(config) = builder.config.target_config.get(&target) {
|
||||
|
@ -1983,6 +1982,8 @@ impl Step for LlvmTools {
|
|||
}
|
||||
}
|
||||
|
||||
builder.ensure(crate::native::Llvm { target });
|
||||
|
||||
let mut tarball = Tarball::new(builder, "llvm-tools", &target.triple);
|
||||
tarball.set_overlay(OverlayKind::LLVM);
|
||||
tarball.is_preview(true);
|
||||
|
|
|
@ -1408,6 +1408,10 @@ impl Build {
|
|||
|
||||
/// Copies a file from `src` to `dst`
|
||||
pub fn copy(&self, src: &Path, dst: &Path) {
|
||||
self.copy_internal(src, dst, false);
|
||||
}
|
||||
|
||||
fn copy_internal(&self, src: &Path, dst: &Path, dereference_symlinks: bool) {
|
||||
if self.config.dry_run {
|
||||
return;
|
||||
}
|
||||
|
@ -1417,15 +1421,22 @@ impl Build {
|
|||
}
|
||||
let _ = fs::remove_file(&dst);
|
||||
let metadata = t!(src.symlink_metadata());
|
||||
let mut src = src.to_path_buf();
|
||||
if metadata.file_type().is_symlink() {
|
||||
let link = t!(fs::read_link(src));
|
||||
t!(symlink_file(link, dst));
|
||||
} else if let Ok(()) = fs::hard_link(src, dst) {
|
||||
if dereference_symlinks {
|
||||
src = t!(fs::canonicalize(src));
|
||||
} else {
|
||||
let link = t!(fs::read_link(src));
|
||||
t!(symlink_file(link, dst));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if let Ok(()) = fs::hard_link(&src, dst) {
|
||||
// Attempt to "easy copy" by creating a hard link
|
||||
// (symlinks don't work on windows), but if that fails
|
||||
// just fall back to a slow `copy` operation.
|
||||
} else {
|
||||
if let Err(e) = fs::copy(src, dst) {
|
||||
if let Err(e) = fs::copy(&src, dst) {
|
||||
panic!("failed to copy `{}` to `{}`: {}", src.display(), dst.display(), e)
|
||||
}
|
||||
t!(fs::set_permissions(dst, metadata.permissions()));
|
||||
|
@ -1497,20 +1508,10 @@ impl Build {
|
|||
let dst = dstdir.join(src.file_name().unwrap());
|
||||
self.verbose_than(1, &format!("Install {:?} to {:?}", src, dst));
|
||||
t!(fs::create_dir_all(dstdir));
|
||||
drop(fs::remove_file(&dst));
|
||||
{
|
||||
if !src.exists() {
|
||||
panic!("Error: File \"{}\" not found!", src.display());
|
||||
}
|
||||
let metadata = t!(src.symlink_metadata());
|
||||
if let Err(e) = fs::copy(&src, &dst) {
|
||||
panic!("failed to copy `{}` to `{}`: {}", src.display(), dst.display(), e)
|
||||
}
|
||||
t!(fs::set_permissions(&dst, metadata.permissions()));
|
||||
let atime = FileTime::from_last_access_time(&metadata);
|
||||
let mtime = FileTime::from_last_modification_time(&metadata);
|
||||
t!(filetime::set_file_times(&dst, atime, mtime));
|
||||
if !src.exists() {
|
||||
panic!("Error: File \"{}\" not found!", src.display());
|
||||
}
|
||||
self.copy_internal(src, &dst, true);
|
||||
chmod(&dst, perms);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue