From ce86629c5f9b572935194c82b3f6cd8d40592ca1 Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Fri, 26 Sep 2025 15:01:01 +0100 Subject: [PATCH 1/5] Move -Cembed-bitcode --- library/Cargo.toml | 18 ++++++++++++ src/bootstrap/src/core/build_steps/compile.rs | 7 ----- src/bootstrap/src/core/build_steps/dist.rs | 2 +- src/bootstrap/src/core/build_steps/test.rs | 5 ++-- src/bootstrap/src/core/builder/cargo.rs | 29 ++++++++++++++----- src/bootstrap/src/lib.rs | 10 +++++-- 6 files changed, 50 insertions(+), 21 deletions(-) diff --git a/library/Cargo.toml b/library/Cargo.toml index e30e624094285..2b664ec9bc825 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 02940a80295b7..a2345ebef77ba 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -673,13 +673,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 0efe0cbbc80f0..7abb44b0a677a 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1005,7 +1005,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 d888e63275cda..9ccb2669496f1 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -887,8 +887,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 093a754f1a4b7..5c65913af00b5 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -103,9 +103,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 { @@ -134,7 +134,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 { @@ -400,8 +404,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 { @@ -1396,9 +1400,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, @@ -1409,9 +1422,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 a31eb0c1c8012..c71477237f07d 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` From 88a59742345aa67975812cf563a5b30dfeff24b0 Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Fri, 26 Sep 2025 15:24:44 +0100 Subject: [PATCH 2/5] Move frame pointers --- library/Cargo.toml | 5 +++++ src/bootstrap/src/core/build_steps/compile.rs | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library/Cargo.toml b/library/Cargo.toml index 2b664ec9bc825..a1f64a4a32373 100644 --- a/library/Cargo.toml +++ b/library/Cargo.toml @@ -64,12 +64,17 @@ rustflags = [ # Until Cargo can rebuild the standard library with the user profile's `lto` # setting, Cargo will force this to be `no` "-Cembed-bitcode=yes", + # Enable frame pointers + "-Zunstable-options", + "-Cforce-frame-pointers=non-leaf", ] [profile.dist.package.panic_abort] rustflags = [ "-Cpanic=abort", "-Cembed-bitcode=yes", + "-Zunstable-options", + "-Cforce-frame-pointers=non-leaf", ] [patch.crates-io] diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index a2345ebef77ba..2fb0831a18cc4 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -687,11 +687,6 @@ pub fn std_cargo( cargo.rustflag("-Cforce-unwind-tables=yes"); } - // Enable frame pointers by default for the library. Note that they are still controlled by a - // separate setting for the compiler. - cargo.rustflag("-Zunstable-options"); - cargo.rustflag("-Cforce-frame-pointers=non-leaf"); - let html_root = format!("-Zcrate-attr=doc(html_root_url=\"{}/\")", builder.doc_rust_lang_org_channel(),); cargo.rustflag(&html_root); From 7c01a90f516679406af0ec87fbddbcd4e212147c Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Tue, 30 Sep 2025 13:51:11 +0100 Subject: [PATCH 3/5] Move debuginfo=1 --- library/Cargo.toml | 2 ++ src/ci/run.sh | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/Cargo.toml b/library/Cargo.toml index a1f64a4a32373..2a2c015811b8e 100644 --- a/library/Cargo.toml +++ b/library/Cargo.toml @@ -59,6 +59,8 @@ rustflags = ["-Cpanic=abort"] # in the user's profile. [profile.dist] inherits = "release" +codegen-units = 1 +debug = 1 # "limited" rustflags = [ # Unconditionally embedding bitcode is necessary for when users enable LTO. # Until Cargo can rebuild the standard library with the user profile's `lto` diff --git a/src/ci/run.sh b/src/ci/run.sh index b486f0525f40d..583ad4461bc3f 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -120,8 +120,6 @@ if [ "$DEPLOY$DEPLOY_ALT" = "1" ]; then if [ "$DEPLOY_ALT" != "" ] && isLinux; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --debuginfo-level=2" - else - RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --debuginfo-level-std=1" fi if [ "$NO_LLVM_ASSERTIONS" = "1" ]; then From 890bbd15bee410ac39338f1f48399262e48a841b Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Tue, 30 Sep 2025 17:13:07 +0100 Subject: [PATCH 4/5] Move symbol mangling --- src/bootstrap/src/core/builder/cargo.rs | 34 ++++++++++--------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 5c65913af00b5..45044502a8f91 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -652,23 +652,15 @@ impl Builder<'_> { rustflags.arg(sysroot_str); } - let use_new_symbol_mangling = match self.config.rust_new_symbol_mangling { - Some(setting) => { - // If an explicit setting is given, use that - setting - } - // Per compiler-team#938, v0 mangling is used on nightly - None if self.config.channel == "dev" || self.config.channel == "nightly" => true, - None => { - if mode == Mode::Std { - // The standard library defaults to the legacy scheme - false - } else { - // The compiler and tools default to the new scheme - true - } + let use_new_symbol_mangling = self.config.rust_new_symbol_mangling.or_else(|| { + if mode != Mode::Std { + // The compiler and tools default to the new scheme + Some(true) + } else { + // std follows the flag's default, which per compiler-team#938 is v0 on nightly + None } - }; + }); // By default, windows-rs depends on a native library that doesn't get copied into the // sysroot. Passing this cfg enables raw-dylib support instead, which makes the native @@ -679,11 +671,11 @@ impl Builder<'_> { rustflags.arg("--cfg=windows_raw_dylib"); } - if use_new_symbol_mangling { - rustflags.arg("-Csymbol-mangling-version=v0"); - } else { - rustflags.arg("-Csymbol-mangling-version=legacy"); - } + rustflags.arg(match use_new_symbol_mangling { + Some(true) => "-Csymbol-mangling-version=v0", + Some(false) => "-Csymbol-mangling-version=legacy", + None => "", + }); // Always enable move/copy annotations for profiler visibility (non-stage0 only). // Note that -Zannotate-moves is only effective with debugging info enabled. From 0bae09c2a998c8fdb6a3dbb6f4e379fa25d485a9 Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Mon, 6 Oct 2025 16:53:54 +0100 Subject: [PATCH 5/5] Configure test's unstable feature gate when built outside of bootstrap This uses a build probe to figure out the current toolchain version - the only alternative to this is bespoke logic in Cargo to tell `test` when the toolchain is stable/unstable. The behaviour should be the same as when using `CFG_DISABLE_UNSTABLE_FEATURES` unless an arbitrary channel is provided to bootstrap, which I believe necessitates a fork anyway. --- library/test/build.rs | 11 +++++++++++ library/test/src/cli.rs | 11 +++++------ src/bootstrap/src/core/build_steps/compile.rs | 6 ------ 3 files changed, 16 insertions(+), 12 deletions(-) create mode 100644 library/test/build.rs diff --git a/library/test/build.rs b/library/test/build.rs new file mode 100644 index 0000000000000..a2bc8936b5195 --- /dev/null +++ b/library/test/build.rs @@ -0,0 +1,11 @@ +fn main() { + println!("cargo:rustc-check-cfg=cfg(enable_unstable_features)"); + + let rustc = std::env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); + let version = std::process::Command::new(rustc).arg("-vV").output().unwrap(); + let stdout = String::from_utf8(version.stdout).unwrap(); + + if stdout.contains("nightly") || stdout.contains("dev") { + println!("cargo:rustc-cfg=enable_unstable_features"); + } +} diff --git a/library/test/src/cli.rs b/library/test/src/cli.rs index 35291cc15c918..172785936b207 100644 --- a/library/test/src/cli.rs +++ b/library/test/src/cli.rs @@ -314,15 +314,14 @@ fn parse_opts_impl(matches: getopts::Matches) -> OptRes { Ok(test_opts) } -// FIXME: Copied from librustc_ast until linkage errors are resolved. Issue #47566 fn is_nightly() -> bool { - // Whether this is a feature-staged build, i.e., on the beta or stable channel - let disable_unstable_features = - option_env!("CFG_DISABLE_UNSTABLE_FEATURES").map(|s| s != "0").unwrap_or(false); - // Whether we should enable unstable features for bootstrapping + // Whether the current rustc version should allow unstable features + let enable_unstable_features = cfg!(enable_unstable_features); + + // The runtime override for unstable features let bootstrap = env::var("RUSTC_BOOTSTRAP").is_ok(); - bootstrap || !disable_unstable_features + bootstrap || enable_unstable_features } // Gets the CLI options associated with `report-time` feature. diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 2fb0831a18cc4..5e1141221b323 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -619,12 +619,6 @@ pub fn std_cargo( CompilerBuiltins::BuildRustOnly => "", }; - // `libtest` uses this to know whether or not to support - // `-Zunstable-options`. - if !builder.unstable_features() { - cargo.env("CFG_DISABLE_UNSTABLE_FEATURES", "1"); - } - for krate in crates { cargo.args(["-p", krate]); }