diff --git a/library/Cargo.toml b/library/Cargo.toml index e30e62409428..2b664ec9bc82 100644 --- a/library/Cargo.toml +++ b/library/Cargo.toml @@ -54,6 +54,24 @@ rustflags = ["-Cpanic=abort"] [profile.release.package.panic_abort] rustflags = ["-Cpanic=abort"] +# The "dist" profile is used by bootstrap for prebuilt libstd artifacts +# These settings ensure that the prebuilt artifacts support a variety of features +# in the user's profile. +[profile.dist] +inherits = "release" +rustflags = [ + # Unconditionally embedding bitcode is necessary for when users enable LTO. + # Until Cargo can rebuild the standard library with the user profile's `lto` + # setting, Cargo will force this to be `no` + "-Cembed-bitcode=yes", +] + +[profile.dist.package.panic_abort] +rustflags = [ + "-Cpanic=abort", + "-Cembed-bitcode=yes", +] + [patch.crates-io] # See comments in `library/rustc-std-workspace-core/README.md` for what's going on here rustc-std-workspace-core = { path = 'rustc-std-workspace-core' } diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 651ff03a8690..2ea4bf96c86d 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -680,13 +680,6 @@ pub fn std_cargo( } } - // By default, rustc uses `-Cembed-bitcode=yes`, and Cargo overrides that - // with `-Cembed-bitcode=no` for non-LTO builds. However, libstd must be - // built with bitcode so that the produced rlibs can be used for both LTO - // builds (which use bitcode) and non-LTO builds (which use object code). - // So we override the override here! - cargo.rustflag("-Cembed-bitcode=yes"); - if builder.config.rust_lto == RustcLto::Off { cargo.rustflag("-Clto=off"); } diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 8ba05a7fa3a7..84ab15781cdd 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1008,7 +1008,7 @@ impl Step for Analysis { let src = builder .stage_out(compiler, Mode::Std) .join(target) - .join(builder.cargo_dir()) + .join(builder.cargo_dir(Mode::Std)) .join("deps") .join("save-analysis"); diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index f3a1c6b0e3dd..786c08cce17a 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -927,8 +927,9 @@ impl Step for Clippy { cargo.env("RUSTC_TEST_SUITE", builder.rustc(build_compiler)); cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(build_compiler)); - let host_libs = - builder.stage_out(build_compiler, Mode::ToolRustcPrivate).join(builder.cargo_dir()); + let host_libs = builder + .stage_out(build_compiler, Mode::ToolRustcPrivate) + .join(builder.cargo_dir(Mode::ToolRustcPrivate)); cargo.env("HOST_LIBS", host_libs); // Build the standard library that the tests can use. diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index dda0b40cb69e..6acffc1bf2c1 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -106,9 +106,9 @@ pub struct Cargo { rustdocflags: Rustflags, hostflags: HostFlags, allow_features: String, - release_build: bool, build_compiler_stage: u32, extra_rustflags: Vec, + profile: Option<&'static str>, } impl Cargo { @@ -137,7 +137,11 @@ impl Cargo { } pub fn release_build(&mut self, release_build: bool) { - self.release_build = release_build; + self.profile = if release_build { Some("release") } else { None }; + } + + pub fn profile(&mut self, profile: &'static str) { + self.profile = Some(profile); } pub fn compiler(&self) -> Compiler { @@ -407,8 +411,8 @@ impl Cargo { impl From for BootstrapCommand { fn from(mut cargo: Cargo) -> BootstrapCommand { - if cargo.release_build { - cargo.args.insert(0, "--release".into()); + if let Some(profile) = cargo.profile { + cargo.args.insert(0, format!("--profile={profile}").into()); } for arg in &cargo.extra_rustflags { @@ -1434,9 +1438,18 @@ impl Builder<'_> { .unwrap_or(&self.config.rust_rustflags) .clone(); - let release_build = self.config.rust_optimize.is_release() && - // cargo bench/install do not accept `--release` and miri doesn't want it - !matches!(cmd_kind, Kind::Bench | Kind::Install | Kind::Miri | Kind::MiriSetup | Kind::MiriTest); + let profile = + if matches!(cmd_kind, Kind::Bench | Kind::Miri | Kind::MiriSetup | Kind::MiriTest) { + // Use the default profile for bench/miri + None + } else { + match (mode, self.config.rust_optimize.is_release()) { + // Some std configuration exists in its own profile + (Mode::Std, true) => Some("dist"), + (_, true) => Some("release"), + (_, false) => Some("dev"), + } + }; Cargo { command: cargo, @@ -1448,9 +1461,9 @@ impl Builder<'_> { rustdocflags, hostflags, allow_features, - release_build, build_compiler_stage, extra_rustflags, + profile, } } } diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 857c0539e7d2..7af96bca44bd 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -898,8 +898,12 @@ impl Build { /// Component directory that Cargo will produce output into (e.g. /// release/debug) - fn cargo_dir(&self) -> &'static str { - if self.config.rust_optimize.is_release() { "release" } else { "debug" } + fn cargo_dir(&self, mode: Mode) -> &'static str { + match (mode, self.config.rust_optimize.is_release()) { + (Mode::Std, true) => "dist", + (_, true) => "release", + (_, false) => "debug", + } } fn tools_dir(&self, build_compiler: Compiler) -> PathBuf { @@ -956,7 +960,7 @@ impl Build { /// running a particular compiler, whether or not we're building the /// standard library, and targeting the specified architecture. fn cargo_out(&self, build_compiler: Compiler, mode: Mode, target: TargetSelection) -> PathBuf { - self.stage_out(build_compiler, mode).join(target).join(self.cargo_dir()) + self.stage_out(build_compiler, mode).join(target).join(self.cargo_dir(mode)) } /// Root output directory of LLVM for `target`