summaryrefslogtreecommitdiffstats
path: root/build/build-rust/rust-vendor-std.patch
diff options
context:
space:
mode:
Diffstat (limited to 'build/build-rust/rust-vendor-std.patch')
-rw-r--r--build/build-rust/rust-vendor-std.patch80
1 files changed, 80 insertions, 0 deletions
diff --git a/build/build-rust/rust-vendor-std.patch b/build/build-rust/rust-vendor-std.patch
new file mode 100644
index 0000000000..b068f9de54
--- /dev/null
+++ b/build/build-rust/rust-vendor-std.patch
@@ -0,0 +1,80 @@
+Teaches Rust's build system to vendor std's dependencies into the
+rust-src component.
+
+This was originally landed in https://github.com/rust-lang/rust/pull/78790
+but was backed out for causing some breakage for distro maintainers who
+need to build Rust itself in a vendored/offline context. It doesn't actually
+fetch anything interesting from crates.io, just the magic fake std/core crates
+that exist to make the build work right. Those crates *are* vendored but
+their contents are ignored in favour of the actual stdlib.
+
+For firefox's purposes, these patches still work fine, and are necessary
+to make -Zbuild-std work in a vendored environment.
+
+diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
+index 3cb0eccd324..a3b8154c024 100644
+--- a/src/bootstrap/dist.rs
++++ b/src/bootstrap/dist.rs
+@@ -905,6 +905,30 @@ fn run(self, builder: &Builder<'_>) -> GeneratedTarball {
+ 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);
++
+ tarball.generate()
+ }
+ }
+diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
+index 3ed53452309..1fc0d887748 100644
+--- a/src/bootstrap/lib.rs
++++ b/src/bootstrap/lib.rs
+@@ -1437,6 +1437,27 @@ fn read_stamp_file(&self, stamp: &Path) -> Vec<(PathBuf, DependencyType)> {
+ 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) {
+ self.copy_internal(src, dst, false);