diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index bdab12db43502..5ce5737f318c7 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1040,6 +1040,30 @@ impl Step for Src { builder.copy(&builder.src.join(file), &dst_src.join(file)); } + // libtest includes std and everything else, so vendoring it + // creates exactly what's needed for `cargo -Zbuild-std` or any + // other analysis of the stdlib's source. Cargo also needs help + // finding the lock, so we copy it to libtest temporarily. + // + // Note that this requires std to only have one version of each + // crate. e.g. two versions of getopts won't be patchable. + let dst_libtest = dst_src.join("library/test"); + let dst_vendor = dst_src.join("vendor"); + let root_lock = dst_src.join("Cargo.lock"); + let temp_lock = dst_libtest.join("Cargo.lock"); + + // `cargo vendor` will delete everything from the lockfile that + // isn't used by libtest, so we need to not use any links! + builder.really_copy(&root_lock, &temp_lock); + + let mut cmd = Command::new(&builder.initial_cargo); + cmd.arg("vendor").arg(dst_vendor).current_dir(&dst_libtest); + builder.info("Dist src"); + let _time = timeit(builder); + builder.run(&mut cmd); + + builder.remove(&temp_lock); + // Create source tarball in rust-installer format let mut cmd = rust_installer(builder); cmd.arg("generate") @@ -1056,8 +1080,6 @@ impl Step for Src { .arg("--component-name=rust-src") .arg("--legacy-manifest-dirs=rustlib,cargo"); - builder.info("Dist src"); - let _time = timeit(builder); builder.run(&mut cmd); builder.remove_dir(&image); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 0878b0ff78930..4d3d945ed411e 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -1167,6 +1167,27 @@ impl Build { paths } + /// Copies a file from `src` to `dst` and doesn't use links, so + /// that the copy can be modified without affecting the original. + pub fn really_copy(&self, src: &Path, dst: &Path) { + if self.config.dry_run { + return; + } + self.verbose_than(1, &format!("Copy {:?} to {:?}", src, dst)); + if src == dst { + return; + } + let _ = fs::remove_file(&dst); + 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)); + } + /// Copies a file from `src` to `dst` pub fn copy(&self, src: &Path, dst: &Path) { if self.config.dry_run {