From 8714345d961e7b1d2a9ee0425766215996855b86 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 5 May 2026 15:53:37 +0200 Subject: [PATCH 1/2] Include vendored sources in the rust-src component In the future this can be used by build-std, but until then it is still useful for allowing rust-analyzer to work offline. This increases the unpacked size by 24MB (from 116MB to 140MB) and the compressed size by only 2MB (from 18MB to 20MB) --- src/bootstrap/src/core/build_steps/dist.rs | 22 +++++- src/bootstrap/src/core/build_steps/run.rs | 5 +- src/bootstrap/src/core/build_steps/vendor.rs | 75 +++++++++++++------- 3 files changed, 74 insertions(+), 28 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 222b982073280..83d295e615288 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -27,7 +27,7 @@ use crate::core::build_steps::gcc::GccTargetPair; use crate::core::build_steps::tool::{ self, RustcPrivateCompilers, ToolTargetBuildMode, get_tool_target_compiler, }; -use crate::core::build_steps::vendor::{VENDOR_DIR, Vendor}; +use crate::core::build_steps::vendor::Vendor; use crate::core::build_steps::{compile, llvm}; use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step, StepMetadata}; use crate::core::config::{GccCiMode, TargetSelection}; @@ -1211,6 +1211,19 @@ impl Step for Src { &dst_src, ); + // Vendor all Cargo dependencies + let vendor = builder.ensure(Vendor { + sync_args: vec![], + versioned_dirs: true, + root_dir: dst_src.clone(), + output_dir: dst_src.clone(), + only_library_workspace: true, + }); + + let library_cargo_config_dir = dst_src.join("library").join(".cargo"); + builder.create_dir(&library_cargo_config_dir); + builder.create(&library_cargo_config_dir.join("config.toml"), &vendor.config_library); + tarball.generate() } @@ -1376,12 +1389,17 @@ fn prepare_source_tarball<'a>( sync_args: pkgs_for_pgo_training.collect(), versioned_dirs: true, root_dir: plain_dst_src.into(), - output_dir: VENDOR_DIR.into(), + output_dir: plain_dst_src.into(), + only_library_workspace: false, }); let cargo_config_dir = plain_dst_src.join(".cargo"); builder.create_dir(&cargo_config_dir); builder.create(&cargo_config_dir.join("config.toml"), &vendor.config); + + let library_cargo_config_dir = plain_dst_src.join("library").join(".cargo"); + builder.create_dir(&library_cargo_config_dir); + builder.create(&library_cargo_config_dir.join("config.toml"), &vendor.config_library); } // Delete extraneous directories diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index 897e03ce71813..943add3e045fb 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -12,7 +12,7 @@ use clap_complete::{Generator, shells}; use crate::core::build_steps::dist::distdir; use crate::core::build_steps::test; use crate::core::build_steps::tool::{self, RustcPrivateCompilers, SourceType, Tool}; -use crate::core::build_steps::vendor::{Vendor, default_paths_to_vendor}; +use crate::core::build_steps::vendor::{VENDOR_DIR, Vendor, default_paths_to_vendor}; use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step, StepMetadata}; use crate::core::config::TargetSelection; use crate::core::config::flags::{get_completion, top_level_help}; @@ -276,8 +276,9 @@ impl Step for GenerateCopyright { versioned_dirs: true, root_dir: builder.src.clone(), output_dir: cache_dir.clone(), + only_library_workspace: false, }); - cache_dir + cache_dir.join(VENDOR_DIR) }; let _guard = builder.group("generate-copyright"); diff --git a/src/bootstrap/src/core/build_steps/vendor.rs b/src/bootstrap/src/core/build_steps/vendor.rs index 36a740c6f35fc..97954f2154250 100644 --- a/src/bootstrap/src/core/build_steps/vendor.rs +++ b/src/bootstrap/src/core/build_steps/vendor.rs @@ -47,8 +47,11 @@ pub(crate) struct Vendor { pub(crate) versioned_dirs: bool, /// The root directory of the source code. pub(crate) root_dir: PathBuf, - /// The target directory for storing vendored dependencies. + /// The root directory for storing vendored dependencies in /vendor + /// and /library/vendor. pub(crate) output_dir: PathBuf, + /// Only vendor crates necessary by the library workspace. + pub(crate) only_library_workspace: bool, } impl Step for Vendor { @@ -68,7 +71,8 @@ impl Step for Vendor { sync_args: run.builder.config.cmd.vendor_sync_args(), versioned_dirs: run.builder.config.cmd.vendor_versioned_dirs(), root_dir: run.builder.src.clone(), - output_dir: run.builder.src.join(VENDOR_DIR), + output_dir: run.builder.src.clone(), + only_library_workspace: false, }); } @@ -77,31 +81,51 @@ impl Step for Vendor { /// This function runs `cargo vendor` and ensures all required submodules /// are initialized before vendoring begins. fn run(self, builder: &Builder<'_>) -> Self::Output { - let _guard = builder.group(&format!("Vendoring sources to {:?}", self.root_dir)); + let _guard = builder.group(&format!("Vendoring sources to {:?}", self.output_dir)); - let mut cmd = command(&builder.initial_cargo); - cmd.arg("vendor"); + let config = if self.only_library_workspace { + String::new() + } else { + let mut cmd = command(&builder.initial_cargo); + cmd.arg("vendor"); - if self.versioned_dirs { - cmd.arg("--versioned-dirs"); - } + if self.versioned_dirs { + cmd.arg("--versioned-dirs"); + } - let to_vendor = default_paths_to_vendor(builder); - // These submodules must be present for `x vendor` to work. - for (_, submodules) in &to_vendor { - for submodule in submodules { - builder.build.require_submodule(submodule, None); + let to_vendor = default_paths_to_vendor(builder); + // These submodules must be present for `x vendor` to work. + for (_, submodules) in &to_vendor { + for submodule in submodules { + builder.build.require_submodule(submodule, None); + } } - } - // Sync these paths by default. - for (p, _) in &to_vendor { - cmd.arg("--sync").arg(p); - } + // Sync these paths by default. + for (p, _) in &to_vendor { + cmd.arg("--sync").arg(p); + } + + // Also sync explicitly requested paths. + for sync_arg in self.sync_args { + cmd.arg("--sync").arg(sync_arg); + } + + // Will read the libstd Cargo.toml + // which uses the unstable `public-dependency` feature. + cmd.env("RUSTC_BOOTSTRAP", "1"); + cmd.env("RUSTC", &builder.initial_rustc); + + cmd.current_dir(&self.root_dir).arg(self.output_dir.join(VENDOR_DIR)); + + cmd.run_capture_stdout(builder).stdout() + }; + + let mut cmd = command(&builder.initial_cargo); + cmd.arg("vendor"); - // Also sync explicitly requested paths. - for sync_arg in self.sync_args { - cmd.arg("--sync").arg(sync_arg); + if self.versioned_dirs { + cmd.arg("--versioned-dirs"); } // Will read the libstd Cargo.toml @@ -109,10 +133,12 @@ impl Step for Vendor { cmd.env("RUSTC_BOOTSTRAP", "1"); cmd.env("RUSTC", &builder.initial_rustc); - cmd.current_dir(self.root_dir).arg(&self.output_dir); + cmd.current_dir(self.root_dir.join("library")) + .arg(self.output_dir.join("library").join(VENDOR_DIR)); + + let config_library = cmd.run_capture_stdout(builder).stdout(); - let config = cmd.run_capture_stdout(builder); - VendorOutput { config: config.stdout() } + VendorOutput { config, config_library } } } @@ -120,4 +146,5 @@ impl Step for Vendor { #[derive(Debug, Clone)] pub(crate) struct VendorOutput { pub(crate) config: String, + pub(crate) config_library: String, } From 57a129113261e6e7b89d795580919ff0b60c9b67 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 11 May 2026 17:46:17 +0200 Subject: [PATCH 2/2] Fix paths in generated .cargo/config.toml for vendoring --- src/bootstrap/src/core/build_steps/dist.rs | 4 ++-- src/bootstrap/src/core/build_steps/run.rs | 2 +- src/bootstrap/src/core/build_steps/vendor.rs | 22 ++++++++++++++------ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 83d295e615288..360b8418d2194 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1216,7 +1216,7 @@ impl Step for Src { sync_args: vec![], versioned_dirs: true, root_dir: dst_src.clone(), - output_dir: dst_src.clone(), + output_dir: None, only_library_workspace: true, }); @@ -1389,7 +1389,7 @@ fn prepare_source_tarball<'a>( sync_args: pkgs_for_pgo_training.collect(), versioned_dirs: true, root_dir: plain_dst_src.into(), - output_dir: plain_dst_src.into(), + output_dir: None, only_library_workspace: false, }); diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index 943add3e045fb..2329bb93b4d3d 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -275,7 +275,7 @@ impl Step for GenerateCopyright { sync_args: Vec::new(), versioned_dirs: true, root_dir: builder.src.clone(), - output_dir: cache_dir.clone(), + output_dir: Some(cache_dir.clone()), only_library_workspace: false, }); cache_dir.join(VENDOR_DIR) diff --git a/src/bootstrap/src/core/build_steps/vendor.rs b/src/bootstrap/src/core/build_steps/vendor.rs index 97954f2154250..246598550553a 100644 --- a/src/bootstrap/src/core/build_steps/vendor.rs +++ b/src/bootstrap/src/core/build_steps/vendor.rs @@ -46,10 +46,13 @@ pub(crate) struct Vendor { /// Determines whether vendored dependencies use versioned directories. pub(crate) versioned_dirs: bool, /// The root directory of the source code. + /// + /// Vendored dependencies will be stored in /vendor and + /// /library/vendor unless overridden by `output_dir`. pub(crate) root_dir: PathBuf, /// The root directory for storing vendored dependencies in /vendor /// and /library/vendor. - pub(crate) output_dir: PathBuf, + pub(crate) output_dir: Option, /// Only vendor crates necessary by the library workspace. pub(crate) only_library_workspace: bool, } @@ -71,7 +74,7 @@ impl Step for Vendor { sync_args: run.builder.config.cmd.vendor_sync_args(), versioned_dirs: run.builder.config.cmd.vendor_versioned_dirs(), root_dir: run.builder.src.clone(), - output_dir: run.builder.src.clone(), + output_dir: None, only_library_workspace: false, }); } @@ -81,7 +84,7 @@ impl Step for Vendor { /// This function runs `cargo vendor` and ensures all required submodules /// are initialized before vendoring begins. fn run(self, builder: &Builder<'_>) -> Self::Output { - let _guard = builder.group(&format!("Vendoring sources to {:?}", self.output_dir)); + let _guard = builder.group(&format!("Vendoring sources to {:?}", self.root_dir)); let config = if self.only_library_workspace { String::new() @@ -116,7 +119,11 @@ impl Step for Vendor { cmd.env("RUSTC_BOOTSTRAP", "1"); cmd.env("RUSTC", &builder.initial_rustc); - cmd.current_dir(&self.root_dir).arg(self.output_dir.join(VENDOR_DIR)); + cmd.current_dir(&self.root_dir); + match &self.output_dir { + None => cmd.arg(VENDOR_DIR), + Some(output_dir) => cmd.arg(output_dir.join(VENDOR_DIR)), + }; cmd.run_capture_stdout(builder).stdout() }; @@ -133,8 +140,11 @@ impl Step for Vendor { cmd.env("RUSTC_BOOTSTRAP", "1"); cmd.env("RUSTC", &builder.initial_rustc); - cmd.current_dir(self.root_dir.join("library")) - .arg(self.output_dir.join("library").join(VENDOR_DIR)); + cmd.current_dir(self.root_dir.join("library")); + match &self.output_dir { + None => cmd.arg(VENDOR_DIR), + Some(output_dir) => cmd.arg(output_dir.join("library").join(VENDOR_DIR)), + }; let config_library = cmd.run_capture_stdout(builder).stdout();