Skip to content

Commit 48543dd

Browse files
authored
Rollup merge of rust-lang#137020 - ferrocene:pa-vendor-sources, r=Kobzol
Pass vendored sources from bootstrap to generate-copyright In addition to doing the vendoring in bootstrap, this PR also loads the list of manifests to parse from bootstrap (instead of hardcoding a smaller list in generate-copyright). This is best reviewed commit-by-commit. Fixes rust-lang#136955
2 parents 005de38 + 92f31b9 commit 48543dd

File tree

7 files changed

+105
-82
lines changed

7 files changed

+105
-82
lines changed

src/bootstrap/src/core/build_steps/dist.rs

+9-19
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use tracing::instrument;
2121

2222
use crate::core::build_steps::doc::DocumentationFormat;
2323
use crate::core::build_steps::tool::{self, Tool};
24-
use crate::core::build_steps::vendor::default_paths_to_vendor;
24+
use crate::core::build_steps::vendor::{VENDOR_DIR, Vendor};
2525
use crate::core::build_steps::{compile, llvm};
2626
use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
2727
use crate::core::config::TargetSelection;
@@ -1052,19 +1052,6 @@ impl Step for PlainSourceTarball {
10521052
if builder.config.dist_vendor {
10531053
builder.require_and_update_all_submodules();
10541054

1055-
// Vendor all Cargo dependencies
1056-
let mut cmd = command(&builder.initial_cargo);
1057-
cmd.arg("vendor").arg("--versioned-dirs");
1058-
1059-
for (p, _) in default_paths_to_vendor(builder) {
1060-
cmd.arg("--sync").arg(p);
1061-
}
1062-
1063-
cmd
1064-
// Will read the libstd Cargo.toml which uses the unstable `public-dependency` feature.
1065-
.env("RUSTC_BOOTSTRAP", "1")
1066-
.current_dir(plain_dst_src);
1067-
10681055
// Vendor packages that are required by opt-dist to collect PGO profiles.
10691056
let pkgs_for_pgo_training = build_helper::LLVM_PGO_CRATES
10701057
.iter()
@@ -1076,15 +1063,18 @@ impl Step for PlainSourceTarball {
10761063
manifest_path.push("Cargo.toml");
10771064
manifest_path
10781065
});
1079-
for manifest_path in pkgs_for_pgo_training {
1080-
cmd.arg("--sync").arg(manifest_path);
1081-
}
10821066

1083-
let config = cmd.run_capture(builder).stdout();
1067+
// Vendor all Cargo dependencies
1068+
let vendor = builder.ensure(Vendor {
1069+
sync_args: pkgs_for_pgo_training.collect(),
1070+
versioned_dirs: true,
1071+
root_dir: plain_dst_src.into(),
1072+
output_dir: VENDOR_DIR.into(),
1073+
});
10841074

10851075
let cargo_config_dir = plain_dst_src.join(".cargo");
10861076
builder.create_dir(&cargo_config_dir);
1087-
builder.create(&cargo_config_dir.join("config.toml"), &config);
1077+
builder.create(&cargo_config_dir.join("config.toml"), &vendor.config);
10881078
}
10891079

10901080
// Delete extraneous directories

src/bootstrap/src/core/build_steps/run.rs

+30-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::Mode;
99
use crate::core::build_steps::dist::distdir;
1010
use crate::core::build_steps::test;
1111
use crate::core::build_steps::tool::{self, SourceType, Tool};
12+
use crate::core::build_steps::vendor::{Vendor, default_paths_to_vendor};
1213
use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
1314
use crate::core::config::TargetSelection;
1415
use crate::core::config::flags::get_completion;
@@ -212,11 +213,39 @@ impl Step for GenerateCopyright {
212213
let dest = builder.out.join("COPYRIGHT.html");
213214
let dest_libstd = builder.out.join("COPYRIGHT-library.html");
214215

216+
let paths_to_vendor = default_paths_to_vendor(builder);
217+
for (_, submodules) in &paths_to_vendor {
218+
for submodule in submodules {
219+
builder.build.require_submodule(submodule, None);
220+
}
221+
}
222+
let cargo_manifests = paths_to_vendor
223+
.into_iter()
224+
.map(|(path, _submodules)| path.to_str().unwrap().to_string())
225+
.inspect(|path| assert!(!path.contains(','), "{path} contains a comma in its name"))
226+
.collect::<Vec<_>>()
227+
.join(",");
228+
229+
let vendored_sources = if let Some(path) = builder.vendored_crates_path() {
230+
path
231+
} else {
232+
let cache_dir = builder.out.join("tmp").join("generate-copyright-vendor");
233+
builder.ensure(Vendor {
234+
sync_args: Vec::new(),
235+
versioned_dirs: true,
236+
root_dir: builder.src.clone(),
237+
output_dir: cache_dir.clone(),
238+
});
239+
cache_dir
240+
};
241+
215242
let mut cmd = builder.tool_cmd(Tool::GenerateCopyright);
243+
cmd.env("CARGO_MANIFESTS", &cargo_manifests);
216244
cmd.env("LICENSE_METADATA", &license_metadata);
217245
cmd.env("DEST", &dest);
218246
cmd.env("DEST_LIBSTD", &dest_libstd);
219-
cmd.env("OUT_DIR", &builder.out);
247+
cmd.env("SRC_DIR", &builder.src);
248+
cmd.env("VENDOR_DIR", &vendored_sources);
220249
cmd.env("CARGO", &builder.initial_cargo);
221250
// it is important that generate-copyright runs from the root of the
222251
// source tree, because it uses relative paths

src/bootstrap/src/core/build_steps/vendor.rs

+18-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use crate::core::build_steps::tool::SUBMODULES_FOR_RUSTBOOK;
44
use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
55
use crate::utils::exec::command;
66

7+
pub const VENDOR_DIR: &str = "vendor";
8+
79
/// Returns the cargo workspaces to vendor for `x vendor` and dist tarballs.
810
///
911
/// Returns a `Vec` of `(path_to_manifest, submodules_required)` where
@@ -29,13 +31,14 @@ pub fn default_paths_to_vendor(builder: &Builder<'_>) -> Vec<(PathBuf, Vec<&'sta
2931

3032
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
3133
pub(crate) struct Vendor {
32-
sync_args: Vec<PathBuf>,
33-
versioned_dirs: bool,
34-
root_dir: PathBuf,
34+
pub(crate) sync_args: Vec<PathBuf>,
35+
pub(crate) versioned_dirs: bool,
36+
pub(crate) root_dir: PathBuf,
37+
pub(crate) output_dir: PathBuf,
3538
}
3639

3740
impl Step for Vendor {
38-
type Output = ();
41+
type Output = VendorOutput;
3942
const DEFAULT: bool = true;
4043
const ONLY_HOSTS: bool = true;
4144

@@ -48,10 +51,13 @@ impl Step for Vendor {
4851
sync_args: run.builder.config.cmd.vendor_sync_args(),
4952
versioned_dirs: run.builder.config.cmd.vendor_versioned_dirs(),
5053
root_dir: run.builder.src.clone(),
54+
output_dir: run.builder.src.join(VENDOR_DIR),
5155
});
5256
}
5357

5458
fn run(self, builder: &Builder<'_>) -> Self::Output {
59+
builder.info(&format!("Vendoring sources to {:?}", self.root_dir));
60+
5561
let mut cmd = command(&builder.initial_cargo);
5662
cmd.arg("vendor");
5763

@@ -81,8 +87,14 @@ impl Step for Vendor {
8187
// which uses the unstable `public-dependency` feature.
8288
cmd.env("RUSTC_BOOTSTRAP", "1");
8389

84-
cmd.current_dir(self.root_dir);
90+
cmd.current_dir(self.root_dir).arg(&self.output_dir);
8591

86-
cmd.run(builder);
92+
let config = cmd.run_capture_stdout(builder);
93+
VendorOutput { config: config.stdout() }
8794
}
8895
}
96+
97+
#[derive(Debug, Clone)]
98+
pub(crate) struct VendorOutput {
99+
pub(crate) config: String,
100+
}

src/bootstrap/src/core/builder/cargo.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -924,8 +924,7 @@ impl Builder<'_> {
924924

925925
if self.config.rust_remap_debuginfo {
926926
let mut env_var = OsString::new();
927-
if self.config.vendor {
928-
let vendor = self.build.src.join("vendor");
927+
if let Some(vendor) = self.build.vendored_crates_path() {
929928
env_var.push(vendor);
930929
env_var.push("=/rust/deps");
931930
} else {

src/bootstrap/src/lib.rs

+7
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ pub use utils::change_tracker::{
5050
CONFIG_CHANGE_HISTORY, find_recent_config_change_ids, human_readable_changes,
5151
};
5252

53+
use crate::core::build_steps::vendor::VENDOR_DIR;
54+
5355
const LLVM_TOOLS: &[&str] = &[
5456
"llvm-cov", // used to generate coverage report
5557
"llvm-nm", // used to inspect binaries; it shows symbol names, their sizes and visibility
@@ -791,6 +793,11 @@ impl Build {
791793
self.out.join(target).join("md-doc")
792794
}
793795

796+
/// Path to the vendored Rust crates.
797+
fn vendored_crates_path(&self) -> Option<PathBuf> {
798+
if self.config.vendor { Some(self.src.join(VENDOR_DIR)) } else { None }
799+
}
800+
794801
/// Returns `true` if this is an external version of LLVM not managed by bootstrap.
795802
/// In particular, we expect llvm sources to be available when this is false.
796803
///

src/tools/generate-copyright/src/cargo_metadata.rs

+6-38
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@ pub enum Error {
1111
Io(#[from] std::io::Error),
1212
#[error("Failed get output from cargo-metadata: {0:?}")]
1313
GettingMetadata(#[from] cargo_metadata::Error),
14-
#[error("Failed to run cargo vendor: {0:?}")]
15-
LaunchingVendor(std::io::Error),
16-
#[error("Failed to complete cargo vendor")]
17-
RunningVendor,
1814
#[error("Bad path {0:?} whilst scraping files")]
1915
Scraping(PathBuf),
2016
}
@@ -43,25 +39,19 @@ pub struct PackageMetadata {
4339
pub is_in_libstd: Option<bool>,
4440
}
4541

46-
/// Use `cargo metadata` and `cargo vendor` to get a list of dependencies and their license data.
42+
/// Use `cargo metadata` to get a list of dependencies and their license data. License files will
43+
/// also be pulled from the vendor path (generated by bootstrap).
4744
///
48-
/// This will involve running `cargo vendor` into `vendor_path` so we can
49-
/// grab the license files.
50-
///
51-
/// Any dependency with a path beginning with `root_path` is ignored, as we
52-
/// assume `reuse` has covered it already.
45+
/// Any dependency with a path beginning with `root_path` is ignored, as we assume `reuse` has
46+
/// covered it already.
5347
pub fn get_metadata_and_notices(
5448
cargo: &Path,
5549
vendor_path: &Path,
5650
root_path: &Path,
57-
manifest_paths: &[&Path],
51+
manifest_paths: &[PathBuf],
5852
) -> Result<BTreeMap<Package, PackageMetadata>, Error> {
5953
let mut output = get_metadata(cargo, root_path, manifest_paths)?;
6054

61-
// Now do a cargo-vendor and grab everything
62-
println!("Vendoring deps into {}...", vendor_path.display());
63-
run_cargo_vendor(cargo, &vendor_path, manifest_paths)?;
64-
6555
// Now for each dependency we found, go and grab any important looking files
6656
for (package, metadata) in output.iter_mut() {
6757
load_important_files(package, metadata, &vendor_path)?;
@@ -77,7 +67,7 @@ pub fn get_metadata_and_notices(
7767
pub fn get_metadata(
7868
cargo: &Path,
7969
root_path: &Path,
80-
manifest_paths: &[&Path],
70+
manifest_paths: &[PathBuf],
8171
) -> Result<BTreeMap<Package, PackageMetadata>, Error> {
8272
let mut output = BTreeMap::new();
8373
// Look at the metadata for each manifest
@@ -113,28 +103,6 @@ pub fn get_metadata(
113103
Ok(output)
114104
}
115105

116-
/// Run cargo-vendor, fetching into the given dir
117-
fn run_cargo_vendor(cargo: &Path, dest: &Path, manifest_paths: &[&Path]) -> Result<(), Error> {
118-
let mut vendor_command = std::process::Command::new(cargo);
119-
vendor_command.env("RUSTC_BOOTSTRAP", "1");
120-
vendor_command.arg("vendor");
121-
vendor_command.arg("--quiet");
122-
vendor_command.arg("--versioned-dirs");
123-
for manifest_path in manifest_paths {
124-
vendor_command.arg("-s");
125-
vendor_command.arg(manifest_path);
126-
}
127-
vendor_command.arg(dest);
128-
129-
let vendor_status = vendor_command.status().map_err(Error::LaunchingVendor)?;
130-
131-
if !vendor_status.success() {
132-
return Err(Error::RunningVendor);
133-
}
134-
135-
Ok(())
136-
}
137-
138106
/// Add important files off disk into this dependency.
139107
///
140108
/// Maybe one-day Cargo.toml will contain enough information that we don't need

src/tools/generate-copyright/src/main.rs

+34-16
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,36 @@ mod cargo_metadata;
1717
fn main() -> Result<(), Error> {
1818
let dest_file = env_path("DEST")?;
1919
let libstd_dest_file = env_path("DEST_LIBSTD")?;
20-
let out_dir = env_path("OUT_DIR")?;
20+
let src_dir = env_path("SRC_DIR")?;
21+
let vendor_dir = env_path("VENDOR_DIR")?;
2122
let cargo = env_path("CARGO")?;
2223
let license_metadata = env_path("LICENSE_METADATA")?;
2324

24-
let root_path = std::path::absolute(".")?;
25+
let cargo_manifests = env_string("CARGO_MANIFESTS")?
26+
.split(",")
27+
.map(|manifest| manifest.into())
28+
.collect::<Vec<PathBuf>>();
29+
let library_manifests = cargo_manifests
30+
.iter()
31+
.filter(|path| {
32+
if let Ok(stripped) = path.strip_prefix(&src_dir) {
33+
stripped.starts_with("library")
34+
} else {
35+
panic!("manifest {path:?} not relative to source dir {src_dir:?}");
36+
}
37+
})
38+
.cloned()
39+
.collect::<Vec<_>>();
2540

2641
// Scan Cargo dependencies
27-
let mut collected_cargo_metadata = cargo_metadata::get_metadata_and_notices(
28-
&cargo,
29-
&out_dir.join("vendor"),
30-
&root_path,
31-
&[
32-
Path::new("./Cargo.toml"),
33-
Path::new("./src/tools/cargo/Cargo.toml"),
34-
Path::new("./library/Cargo.toml"),
35-
],
36-
)?;
42+
let mut collected_cargo_metadata =
43+
cargo_metadata::get_metadata_and_notices(&cargo, &vendor_dir, &src_dir, &cargo_manifests)?;
3744

3845
let library_collected_cargo_metadata = cargo_metadata::get_metadata_and_notices(
3946
&cargo,
40-
&out_dir.join("library-vendor"),
41-
&root_path,
42-
&[Path::new("./library/Cargo.toml")],
47+
&vendor_dir,
48+
&src_dir,
49+
&library_manifests,
4350
)?;
4451

4552
for (key, value) in collected_cargo_metadata.iter_mut() {
@@ -54,7 +61,7 @@ fn main() -> Result<(), Error> {
5461
let library_collected_tree_metadata = Metadata {
5562
files: collected_tree_metadata
5663
.files
57-
.trim_clone(&Path::new("./library"), &Path::new("."))
64+
.trim_clone(&src_dir.join("library"), &src_dir)
5865
.unwrap(),
5966
};
6067

@@ -193,6 +200,17 @@ struct License {
193200
copyright: Vec<String>,
194201
}
195202

203+
/// Grab an environment variable as string, or fail nicely.
204+
fn env_string(var: &str) -> Result<String, Error> {
205+
match std::env::var(var) {
206+
Ok(var) => Ok(var),
207+
Err(std::env::VarError::NotUnicode(_)) => {
208+
anyhow::bail!("environment variable {var} is not utf-8")
209+
}
210+
Err(std::env::VarError::NotPresent) => anyhow::bail!("missing environment variable {var}"),
211+
}
212+
}
213+
196214
/// Grab an environment variable as a PathBuf, or fail nicely.
197215
fn env_path(var: &str) -> Result<PathBuf, Error> {
198216
if let Some(var) = std::env::var_os(var) {

0 commit comments

Comments
 (0)