tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

rust-vendor-std.patch (5218B)


      1 Teaches Rust's build system to vendor `std`'s dependencies into the
      2 `rust-src` component.
      3 
      4 This was originally landed in <https://github.com/rust-lang/rust/pull/78790>,
      5 and <https://github.com/rust-lang/cargo/pull/8834>, but was backed out for
      6 causing breakage in other situations.
      7 
      8 Since then, things have changed in cargo, such that it is now possible to use
      9 a simpler approach that only relies on tweaking what is shipped in rust.
     10 
     11 diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
     12 index 5cfaa6a7c77..65c8abcb4f8 100644
     13 --- a/src/bootstrap/src/core/build_steps/dist.rs
     14 +++ b/src/bootstrap/src/core/build_steps/dist.rs
     15 @@ -1016,6 +1016,97 @@ fn run(self, builder: &Builder<'_>) -> GeneratedTarball {
     16             &dst_src,
     17         );
     18 
     19 +        // cargo's -Z build-std doesn't work properly alongside vendoring.
     20 +        // To work around the issue, we vendor the libstd dependencies in the
     21 +        // rust-src package, and alter libstd's Cargo.toml to contain
     22 +        // patch.crates-io entries pointing to the vendored versions.
     23 +        let root_dir = dst_src.join("library");
     24 +        let root_lock = root_dir.join("Cargo.lock");
     25 +        if root_lock.exists() {
     26 +            use std::collections::HashMap;
     27 +
     28 +            use toml::map::Map;
     29 +            use toml::Value;
     30 +
     31 +            let dst_vendor = dst_src.join("vendor");
     32 +
     33 +            let mut cmd = command(&builder.initial_cargo);
     34 +            cmd.arg("vendor").arg(&dst_vendor).current_dir(&root_dir);
     35 +            // library/std/Cargo.toml uses the `public-dependency` nightly cargo feature.
     36 +            cmd.env("RUSTC_BOOTSTRAP", "1");
     37 +            builder.info("Dist src");
     38 +            let _time = timeit(builder);
     39 +            cmd.run(builder);
     40 +
     41 +            // Ideally, we would add the .cargo/config.toml that `cargo vendor` outputs,
     42 +            // but cargo doesn't read it when building libstd. So instead, we add
     43 +            // [patch.crates-io] entries to Cargo.toml for all vendored packages.
     44 +            let cargo_toml_path = root_lock.with_extension("toml");
     45 +            let cargo_toml_str = t!(std::fs::read_to_string(&cargo_toml_path));
     46 +            let mut manifest: Value = t!(toml::from_str(&cargo_toml_str));
     47 +
     48 +            let patch_table = t!(manifest
     49 +                .get_mut("patch")
     50 +                .and_then(|p| p.as_table_mut())
     51 +                .and_then(|p| p.get_mut("crates-io"))
     52 +                .and_then(|c| c.as_table_mut())
     53 +                .ok_or("[patch.crates-io] section not found"));
     54 +
     55 +            let mut packages_by_name: HashMap<String, Vec<String>> = HashMap::new();
     56 +
     57 +            for entry in builder.read_dir(&dst_vendor) {
     58 +                let path = entry.path();
     59 +
     60 +                // Check for Cargo.toml
     61 +                let crate_cargo_toml_path = path.join("Cargo.toml");
     62 +                if !crate_cargo_toml_path.exists() {
     63 +                    continue;
     64 +                }
     65 +
     66 +                // Parse package name from Cargo.toml
     67 +                let crate_cargo_toml_str = t!(std::fs::read_to_string(&crate_cargo_toml_path));
     68 +                let crate_cargo_toml: Value = t!(toml::from_str(&crate_cargo_toml_str));
     69 +                let pkg_name = t!(crate_cargo_toml
     70 +                    .get("package")
     71 +                    .and_then(|p| p.get("name"))
     72 +                    .and_then(|n| n.as_str())
     73 +                    .ok_or("package.name not found"));
     74 +                let dir_name = path.file_name().unwrap().to_string_lossy().into_owned();
     75 +                packages_by_name
     76 +                    .entry(pkg_name.to_string())
     77 +                    .or_insert_with(Vec::new)
     78 +                    .push(dir_name);
     79 +            }
     80 +
     81 +            for (pkg_name, dirs) in &packages_by_name {
     82 +                for dir_name in dirs.iter() {
     83 +                    // What we want in the normal case:
     84 +                    //   [patch.crates-io.crate]
     85 +                    //   path = "../vendor/crate"
     86 +                    // When the directory name is different (usually when it contains a
     87 +                    // version) we want the following:
     88 +                    //   [patch.crates-io.crate-version]
     89 +                    //   package = "crate"
     90 +                    //   path = "../vendor/crate-version"
     91 +                    let mut patch_value = Map::new();
     92 +                    let name = dir_name.replace('.', "_").replace('+', "_");
     93 +                    if &name != pkg_name {
     94 +                        patch_value.insert("package".to_string(), pkg_name.clone().into());
     95 +                    }
     96 +                    patch_value
     97 +                        .insert("path".to_string(), format!("../vendor/{}", dir_name).into());
     98 +                    patch_table.insert(name, patch_value.into());
     99 +                }
    100 +            }
    101 +
    102 +            // Cargo.toml may be a hardlink to the one in the repository, and
    103 +            // we don't want to modify that, so break the hardlink first.
    104 +            t!(std::fs::remove_file(&cargo_toml_path));
    105 +
    106 +            let new_cargo_toml = t!(toml::to_string_pretty(&manifest));
    107 +            t!(std::fs::write(&cargo_toml_path, new_cargo_toml));
    108 +        }
    109 +
    110         tarball.generate()
    111     }