about summary refs log tree commit diff
path: root/src/bootstrap
diff options
context:
space:
mode:
authorAlexis Beingessner <a.beingessner@gmail.com>2020-11-05 17:18:14 -0500
committerAlexis Beingessner <a.beingessner@gmail.com>2020-11-09 11:20:12 -0500
commitceba2befb4c0ef9cbd9592c66c61a49a71e7a695 (patch)
treee8791adc6e79b013a6e1bddcb7d9af4fe4b4c1d8 /src/bootstrap
parentfe8f02690804d5ee696bd3bca9515f5f71857e3b (diff)
downloadrust-ceba2befb4c0ef9cbd9592c66c61a49a71e7a695.tar.gz
rust-ceba2befb4c0ef9cbd9592c66c61a49a71e7a695.zip
Vendor libtest's dependencies in the rust-src component
This is the Rust side of https://github.com/rust-lang/wg-cargo-std-aware/issues/23
Diffstat (limited to 'src/bootstrap')
-rw-r--r--src/bootstrap/dist.rs26
-rw-r--r--src/bootstrap/lib.rs21
2 files changed, 45 insertions, 2 deletions
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index bdab12db435..5ce5737f318 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 0878b0ff789..4d3d945ed41 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 {