diff --git a/bootstrap.example.toml b/bootstrap.example.toml index 31966af330120..89da6eeb53153 100644 --- a/bootstrap.example.toml +++ b/bootstrap.example.toml @@ -740,11 +740,19 @@ # result (broken, compiling, testing) into this JSON file. #rust.save-toolstates = (path) -# This is an array of the codegen backends that will be compiled for the rustc -# that's being compiled. The default is to only build the LLVM codegen backend, -# and currently the only standard options supported are `"llvm"`, `"cranelift"` -# and `"gcc"`. The first backend in this list will be used as default by rustc -# when no explicit backend is specified. +# This array serves three distinct purposes: +# - Backends in this list will be automatically compiled and included in the sysroot of each +# rustc compiled by bootstrap. +# - The first backend in this list will be configured as the **default codegen backend** by each +# rustc compiled by bootstrap. In other words, if the first backend is e.g. cranelift, then when +# we build a stage 1 rustc, it will by default compile Rust programs using the Cranelift backend. +# This also means that stage 2 rustc would get built by the Cranelift backend. +# - Running `x dist` (without additional arguments, or with `--include-default-paths`) will produce +# a dist component/tarball for the Cranelift backend if it is included in this array. +# +# Note that the LLVM codegen backend is special and will always be built and distributed. +# +# Currently, the only standard options supported here are `"llvm"`, `"cranelift"` and `"gcc"`. #rust.codegen-backends = ["llvm"] # Indicates whether LLD will be compiled and made available in the sysroot for rustc to execute, and diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 95707e37018e9..343242465828e 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -23,8 +23,7 @@ use crate::core::build_steps::tool::{RustcPrivateCompilers, SourceType, copy_lld use crate::core::build_steps::{dist, llvm}; use crate::core::builder; use crate::core::builder::{ - Builder, Cargo, Kind, PathSet, RunConfig, ShouldRun, Step, StepMetadata, TaskPath, - crate_description, + Builder, Cargo, Kind, RunConfig, ShouldRun, Step, StepMetadata, crate_description, }; use crate::core::config::{DebuginfoLevel, LlvmLibunwind, RustcLto, TargetSelection}; use crate::utils::build_stamp; @@ -1543,99 +1542,131 @@ impl Step for RustcLink { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct CodegenBackend { +pub struct GccCodegenBackend { compilers: RustcPrivateCompilers, - backend: CodegenBackendKind, } -fn needs_codegen_config(run: &RunConfig<'_>) -> bool { - let mut needs_codegen_cfg = false; - for path_set in &run.paths { - needs_codegen_cfg = match path_set { - PathSet::Set(set) => set.iter().any(|p| is_codegen_cfg_needed(p, run)), - PathSet::Suite(suite) => is_codegen_cfg_needed(suite, run), - } +impl Step for GccCodegenBackend { + type Output = BuildStamp; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.alias("rustc_codegen_gcc").alias("cg_gcc") } - needs_codegen_cfg -} -pub(crate) const CODEGEN_BACKEND_PREFIX: &str = "rustc_codegen_"; + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(GccCodegenBackend { + compilers: RustcPrivateCompilers::new(run.builder, run.builder.top_stage, run.target), + }); + } -fn is_codegen_cfg_needed(path: &TaskPath, run: &RunConfig<'_>) -> bool { - let path = path.path.to_str().unwrap(); + #[cfg_attr( + feature = "tracing", + instrument( + level = "debug", + name = "GccCodegenBackend::run", + skip_all, + fields( + compilers = ?self.compilers, + ), + ), + )] + fn run(self, builder: &Builder<'_>) -> Self::Output { + let target = self.compilers.target(); + let build_compiler = self.compilers.build_compiler(); - let is_explicitly_called = |p| -> bool { run.builder.paths.contains(p) }; - let should_enforce = run.builder.kind == Kind::Dist || run.builder.kind == Kind::Install; + let stamp = build_stamp::codegen_backend_stamp( + builder, + build_compiler, + target, + &CodegenBackendKind::Gcc, + ); - if path.contains(CODEGEN_BACKEND_PREFIX) { - let mut needs_codegen_backend_config = true; - for backend in run.builder.config.codegen_backends(run.target) { - if path.ends_with(&(CODEGEN_BACKEND_PREFIX.to_owned() + backend.name())) { - needs_codegen_backend_config = false; - } - } - if (is_explicitly_called(&PathBuf::from(path)) || should_enforce) - && needs_codegen_backend_config - { - run.builder.info( - "WARNING: no codegen-backends config matched the requested path to build a codegen backend. \ - HELP: add backend to codegen-backends in bootstrap.toml.", + if builder.config.keep_stage.contains(&build_compiler.stage) { + trace!("`keep-stage` requested"); + builder.info( + "WARNING: Using a potentially old codegen backend. \ + This may not behave well.", ); - return true; + // Codegen backends are linked separately from this step today, so we don't do + // anything here. + return stamp; } + + let mut cargo = builder::Cargo::new( + builder, + build_compiler, + Mode::Codegen, + SourceType::InTree, + target, + Kind::Build, + ); + cargo.arg("--manifest-path").arg(builder.src.join("compiler/rustc_codegen_gcc/Cargo.toml")); + rustc_cargo_env(builder, &mut cargo, target); + + let gcc = builder.ensure(Gcc { target }); + add_cg_gcc_cargo_flags(&mut cargo, &gcc); + + let _guard = builder.msg_rustc_tool( + Kind::Build, + build_compiler.stage, + format_args!("codegen backend gcc"), + build_compiler.host, + target, + ); + let files = run_cargo(builder, cargo, vec![], &stamp, vec![], false, false); + write_codegen_backend_stamp(stamp, files, builder.config.dry_run()) } - false + fn metadata(&self) -> Option { + Some( + StepMetadata::build("rustc_codegen_gcc", self.compilers.target()) + .built_by(self.compilers.build_compiler()), + ) + } } -impl Step for CodegenBackend { - type Output = (); +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct CraneliftCodegenBackend { + pub compilers: RustcPrivateCompilers, +} + +impl Step for CraneliftCodegenBackend { + type Output = BuildStamp; const ONLY_HOSTS: bool = true; - /// Only the backends specified in the `codegen-backends` entry of `bootstrap.toml` are built. - const DEFAULT: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.paths(&["compiler/rustc_codegen_cranelift", "compiler/rustc_codegen_gcc"]) + run.alias("rustc_codegen_cranelift").alias("cg_clif") } fn make_run(run: RunConfig<'_>) { - if needs_codegen_config(&run) { - return; - } - - for backend in run.builder.config.codegen_backends(run.target) { - if backend.is_llvm() { - continue; // Already built as part of rustc - } - - run.builder.ensure(CodegenBackend { - compilers: RustcPrivateCompilers::new( - run.builder, - run.builder.top_stage, - run.target, - ), - backend: backend.clone(), - }); - } + run.builder.ensure(CraneliftCodegenBackend { + compilers: RustcPrivateCompilers::new(run.builder, run.builder.top_stage, run.target), + }); } #[cfg_attr( feature = "tracing", instrument( level = "debug", - name = "CodegenBackend::run", + name = "CraneliftCodegenBackend::run", skip_all, fields( compilers = ?self.compilers, - backend = ?self.backend, ), ), )] - fn run(self, builder: &Builder<'_>) { - let backend = self.backend; + fn run(self, builder: &Builder<'_>) -> Self::Output { let target = self.compilers.target(); let build_compiler = self.compilers.build_compiler(); + let stamp = build_stamp::codegen_backend_stamp( + builder, + build_compiler, + target, + &CodegenBackendKind::Cranelift, + ); + if builder.config.keep_stage.contains(&build_compiler.stage) { trace!("`keep-stage` requested"); builder.info( @@ -1644,11 +1675,9 @@ impl Step for CodegenBackend { ); // Codegen backends are linked separately from this step today, so we don't do // anything here. - return; + return stamp; } - let out_dir = builder.cargo_out(build_compiler, Mode::Codegen, target); - let mut cargo = builder::Cargo::new( builder, build_compiler, @@ -1659,30 +1688,35 @@ impl Step for CodegenBackend { ); cargo .arg("--manifest-path") - .arg(builder.src.join(format!("compiler/{}/Cargo.toml", backend.crate_name()))); + .arg(builder.src.join("compiler/rustc_codegen_cranelift/Cargo.toml")); rustc_cargo_env(builder, &mut cargo, target); - // Ideally, we'd have a separate step for the individual codegen backends, - // like we have in tests (test::CodegenGCC) but that would require a lot of restructuring. - // If the logic gets more complicated, it should probably be done. - if backend.is_gcc() { - let gcc = builder.ensure(Gcc { target }); - add_cg_gcc_cargo_flags(&mut cargo, &gcc); - } - - let tmp_stamp = BuildStamp::new(&out_dir).with_prefix("tmp"); - let _guard = builder.msg_rustc_tool( Kind::Build, build_compiler.stage, - format_args!("codegen backend {}", backend.name()), + format_args!("codegen backend cranelift"), build_compiler.host, target, ); - let files = run_cargo(builder, cargo, vec![], &tmp_stamp, vec![], false, false); - if builder.config.dry_run() { - return; - } + let files = run_cargo(builder, cargo, vec![], &stamp, vec![], false, false); + write_codegen_backend_stamp(stamp, files, builder.config.dry_run()) + } + + fn metadata(&self) -> Option { + Some( + StepMetadata::build("rustc_codegen_cranelift", self.compilers.target()) + .built_by(self.compilers.build_compiler()), + ) + } +} + +/// Write filtered `files` into the passed build stamp and returns it. +fn write_codegen_backend_stamp( + mut stamp: BuildStamp, + files: Vec, + dry_run: bool, +) -> BuildStamp { + if !dry_run { let mut files = files.into_iter().filter(|f| { let filename = f.file_name().unwrap().to_str().unwrap(); is_dylib(f) && filename.contains("rustc_codegen_") @@ -1698,32 +1732,27 @@ impl Step for CodegenBackend { f.display() ); } - let stamp = build_stamp::codegen_backend_stamp(builder, build_compiler, target, &backend); - let codegen_backend = codegen_backend.to_str().unwrap(); - t!(stamp.add_stamp(codegen_backend).write()); - } - fn metadata(&self) -> Option { - Some( - StepMetadata::build(&self.backend.crate_name(), self.compilers.target()) - .built_by(self.compilers.build_compiler()), - ) + let codegen_backend = codegen_backend.to_str().unwrap(); + stamp = stamp.add_stamp(codegen_backend); + t!(stamp.write()); } + stamp } +pub(crate) const CODEGEN_BACKEND_PREFIX: &str = "rustc_codegen_"; + /// Creates the `codegen-backends` folder for a compiler that's about to be /// assembled as a complete compiler. /// -/// This will take the codegen artifacts produced by `compiler` and link them +/// This will take the codegen artifacts recorded in the given `stamp` and link them /// into an appropriate location for `target_compiler` to be a functional /// compiler. fn copy_codegen_backends_to_sysroot( builder: &Builder<'_>, - compiler: Compiler, + stamp: BuildStamp, target_compiler: Compiler, ) { - let target = target_compiler.host; - // Note that this step is different than all the other `*Link` steps in // that it's not assembling a bunch of libraries but rather is primarily // moving the codegen backend into place. The codegen backend of rustc is @@ -1739,25 +1768,18 @@ fn copy_codegen_backends_to_sysroot( return; } - for backend in builder.config.codegen_backends(target) { - if backend.is_llvm() { - continue; // Already built as part of rustc - } - - let stamp = build_stamp::codegen_backend_stamp(builder, compiler, target, backend); - if stamp.path().exists() { - let dylib = t!(fs::read_to_string(stamp.path())); - let file = Path::new(&dylib); - let filename = file.file_name().unwrap().to_str().unwrap(); - // change `librustc_codegen_cranelift-xxxxxx.so` to - // `librustc_codegen_cranelift-release.so` - let target_filename = { - let dash = filename.find('-').unwrap(); - let dot = filename.find('.').unwrap(); - format!("{}-{}{}", &filename[..dash], builder.rust_release(), &filename[dot..]) - }; - builder.copy_link(file, &dst.join(target_filename), FileType::NativeLibrary); - } + if stamp.path().exists() { + let dylib = t!(fs::read_to_string(stamp.path())); + let file = Path::new(&dylib); + let filename = file.file_name().unwrap().to_str().unwrap(); + // change `librustc_codegen_cranelift-xxxxxx.so` to + // `librustc_codegen_cranelift-release.so` + let target_filename = { + let dash = filename.find('-').unwrap(); + let dot = filename.find('.').unwrap(); + format!("{}-{}{}", &filename[..dash], builder.rust_release(), &filename[dot..]) + }; + builder.copy_link(file, &dst.join(target_filename), FileType::NativeLibrary); } } @@ -2166,44 +2188,52 @@ impl Step for Assemble { ); build_compiler.stage = actual_stage; - #[cfg(feature = "tracing")] - let _codegen_backend_span = - span!(tracing::Level::DEBUG, "building requested codegen backends").entered(); - for backend in builder.config.codegen_backends(target_compiler.host) { - if backend.is_llvm() { - debug!("llvm codegen backend is already built as part of rustc"); - continue; // Already built as part of rustc - } + let mut codegen_backend_stamps = vec![]; + { + #[cfg(feature = "tracing")] + let _codegen_backend_span = + span!(tracing::Level::DEBUG, "building requested codegen backends").entered(); + + for backend in builder.config.enabled_codegen_backends(target_compiler.host) { + // FIXME: this is a horrible hack used to make `x check` work when other codegen + // backends are enabled. + // `x check` will check stage 1 rustc, which copies its rmetas to the stage0 sysroot. + // Then it checks codegen backends, which correctly use these rmetas. + // Then it needs to check std, but for that it needs to build stage 1 rustc. + // This copies the build rmetas into the stage0 sysroot, effectively poisoning it, + // because we then have both check and build rmetas in the same sysroot. + // That would be fine on its own. However, when another codegen backend is enabled, + // then building stage 1 rustc implies also building stage 1 codegen backend (even if + // it isn't used for anything). And since that tries to use the poisoned + // rmetas, it fails to build. + // We don't actually need to build rustc-private codegen backends for checking std, + // so instead we skip that. + // Note: this would be also an issue for other rustc-private tools, but that is "solved" + // by check::Std being last in the list of checked things (see + // `Builder::get_step_descriptions`). + if builder.kind == Kind::Check && builder.top_stage == 1 { + continue; + } - // FIXME: this is a horrible hack used to make `x check` work when other codegen - // backends are enabled. - // `x check` will check stage 1 rustc, which copies its rmetas to the stage0 sysroot. - // Then it checks codegen backends, which correctly use these rmetas. - // Then it needs to check std, but for that it needs to build stage 1 rustc. - // This copies the build rmetas into the stage0 sysroot, effectively poisoning it, - // because we then have both check and build rmetas in the same sysroot. - // That would be fine on its own. However, when another codegen backend is enabled, - // then building stage 1 rustc implies also building stage 1 codegen backend (even if - // it isn't used for anything). And since that tries to use the poisoned - // rmetas, it fails to build. - // We don't actually need to build rustc-private codegen backends for checking std, - // so instead we skip that. - // Note: this would be also an issue for other rustc-private tools, but that is "solved" - // by check::Std being last in the list of checked things (see - // `Builder::get_step_descriptions`). - if builder.kind == Kind::Check && builder.top_stage == 1 { - continue; + let prepare_compilers = || { + RustcPrivateCompilers::from_build_and_target_compiler( + build_compiler, + target_compiler, + ) + }; + + let stamp = match backend { + CodegenBackendKind::Cranelift => { + builder.ensure(CraneliftCodegenBackend { compilers: prepare_compilers() }) + } + CodegenBackendKind::Gcc => { + builder.ensure(GccCodegenBackend { compilers: prepare_compilers() }) + } + CodegenBackendKind::Llvm | CodegenBackendKind::Custom(_) => continue, + }; + codegen_backend_stamps.push(stamp); } - builder.ensure(CodegenBackend { - compilers: RustcPrivateCompilers::from_build_and_target_compiler( - build_compiler, - target_compiler, - ), - backend: backend.clone(), - }); } - #[cfg(feature = "tracing")] - drop(_codegen_backend_span); let stage = target_compiler.stage; let host = target_compiler.host; @@ -2264,7 +2294,9 @@ impl Step for Assemble { } debug!("copying codegen backends to sysroot"); - copy_codegen_backends_to_sysroot(builder, build_compiler, target_compiler); + for stamp in codegen_backend_stamps { + copy_codegen_backends_to_sysroot(builder, stamp, target_compiler); + } if builder.config.lld_enabled { let lld_wrapper = diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 0465a071159ba..46f0937d83e39 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1367,38 +1367,39 @@ impl Step for Miri { } #[derive(Debug, Clone, Hash, PartialEq, Eq)] -pub struct CodegenBackend { - pub compiler: Compiler, - pub backend: CodegenBackendKind, +pub struct CraneliftCodegenBackend { + pub build_compiler: Compiler, } -impl Step for CodegenBackend { +impl Step for CraneliftCodegenBackend { type Output = Option; const DEFAULT: bool = true; const ONLY_HOSTS: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("compiler/rustc_codegen_cranelift") + // We only want to build the cranelift backend in `x dist` if the backend was enabled + // in rust.codegen-backends. + // Sadly, we don't have access to the actual for which we're disting clif here.. + // So we just use the host target. + let clif_enabled_by_default = run + .builder + .config + .enabled_codegen_backends(run.builder.host_target) + .contains(&CodegenBackendKind::Cranelift); + run.alias("rustc_codegen_cranelift").default_condition(clif_enabled_by_default) } fn make_run(run: RunConfig<'_>) { - for backend in run.builder.config.codegen_backends(run.target) { - if backend.is_llvm() { - continue; // Already built as part of rustc - } - - run.builder.ensure(CodegenBackend { - compiler: run.builder.compiler(run.builder.top_stage, run.target), - backend: backend.clone(), - }); - } + run.builder.ensure(CraneliftCodegenBackend { + build_compiler: run.builder.compiler_for( + run.builder.top_stage, + run.builder.config.host_target, + run.target, + ), + }); } fn run(self, builder: &Builder<'_>) -> Option { - if builder.config.dry_run() { - return None; - } - // This prevents rustc_codegen_cranelift from being built for "dist" // or "install" on the stable/beta channels. It is not yet stable and // should not be included. @@ -1406,46 +1407,39 @@ impl Step for CodegenBackend { return None; } - if !builder.config.codegen_backends(self.compiler.host).contains(&self.backend) { - return None; - } - - if self.backend.is_cranelift() && !target_supports_cranelift_backend(self.compiler.host) { + let target = self.build_compiler.host; + let compilers = + RustcPrivateCompilers::from_build_compiler(builder, self.build_compiler, target); + if !target_supports_cranelift_backend(target) { builder.info("target not supported by rustc_codegen_cranelift. skipping"); return None; } - let compiler = self.compiler; - let backend = self.backend; + let mut tarball = Tarball::new(builder, "rustc-codegen-cranelift", &target.triple); + tarball.set_overlay(OverlayKind::RustcCodegenCranelift); + tarball.is_preview(true); + tarball.add_legal_and_readme_to("share/doc/rustc_codegen_cranelift"); - let mut tarball = Tarball::new( - builder, - &format!("rustc-codegen-{}", backend.name()), - &compiler.host.triple, - ); - if backend.is_cranelift() { - tarball.set_overlay(OverlayKind::RustcCodegenCranelift); - } else { - panic!("Unknown codegen backend {}", backend.name()); + builder.ensure(compile::CraneliftCodegenBackend { compilers }); + + if builder.config.dry_run() { + return None; } - tarball.is_preview(true); - tarball.add_legal_and_readme_to(format!("share/doc/{}", backend.crate_name())); - let src = builder.sysroot(compiler); - let backends_src = builder.sysroot_codegen_backends(compiler); + let src = builder.sysroot(self.build_compiler); + let backends_src = builder.sysroot_codegen_backends(self.build_compiler); let backends_rel = backends_src .strip_prefix(src) .unwrap() - .strip_prefix(builder.sysroot_libdir_relative(compiler)) + .strip_prefix(builder.sysroot_libdir_relative(self.build_compiler)) .unwrap(); // Don't use custom libdir here because ^lib/ will be resolved again with installer let backends_dst = PathBuf::from("lib").join(backends_rel); - let backend_name = backend.crate_name(); let mut found_backend = false; for backend in fs::read_dir(&backends_src).unwrap() { let file_name = backend.unwrap().file_name(); - if file_name.to_str().unwrap().contains(&backend_name) { + if file_name.to_str().unwrap().contains("rustc_codegen_cranelift") { tarball.add_file( backends_src.join(file_name), &backends_dst, @@ -1458,6 +1452,13 @@ impl Step for CodegenBackend { Some(tarball.generate()) } + + fn metadata(&self) -> Option { + Some( + StepMetadata::dist("rustc_codegen_cranelift", self.build_compiler.host) + .built_by(self.build_compiler), + ) + } } #[derive(Debug, Clone, Hash, PartialEq, Eq)] @@ -1568,9 +1569,8 @@ impl Step for Extended { add_component!("clippy" => Clippy { build_compiler: compiler, target }); add_component!("miri" => Miri { build_compiler: compiler, target }); add_component!("analysis" => Analysis { compiler, target }); - add_component!("rustc-codegen-cranelift" => CodegenBackend { - compiler: builder.compiler(stage, target), - backend: CodegenBackendKind::Cranelift, + add_component!("rustc-codegen-cranelift" => CraneliftCodegenBackend { + build_compiler: compiler, }); add_component!("llvm-bitcode-linker" => LlvmBitcodeLinker { build_compiler: compiler, diff --git a/src/bootstrap/src/core/build_steps/install.rs b/src/bootstrap/src/core/build_steps/install.rs index f628330e9ed4d..acee78dcf59b9 100644 --- a/src/bootstrap/src/core/build_steps/install.rs +++ b/src/bootstrap/src/core/build_steps/install.rs @@ -12,7 +12,7 @@ use crate::core::config::{Config, TargetSelection}; use crate::utils::exec::command; use crate::utils::helpers::t; use crate::utils::tarball::GeneratedTarball; -use crate::{CodegenBackendKind, Compiler, Kind}; +use crate::{Compiler, Kind}; #[cfg(target_os = "illumos")] const SHELL: &str = "bash"; @@ -274,9 +274,8 @@ install!((self, builder, _config), install_sh(builder, "rustc", self.compiler.stage, Some(self.target), &tarball); }; RustcCodegenCranelift, alias = "rustc-codegen-cranelift", Self::should_build(_config), only_hosts: true, { - if let Some(tarball) = builder.ensure(dist::CodegenBackend { - compiler: self.compiler, - backend: CodegenBackendKind::Cranelift, + if let Some(tarball) = builder.ensure(dist::CraneliftCodegenBackend { + build_compiler: self.compiler, }) { install_sh(builder, "rustc-codegen-cranelift", self.compiler.stage, Some(self.target), &tarball); } else { diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 09d2657b666d4..83a3ab730cef7 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -3480,7 +3480,11 @@ impl Step for CodegenCranelift { return; } - if !builder.config.codegen_backends(run.target).contains(&CodegenBackendKind::Cranelift) { + if !builder + .config + .enabled_codegen_backends(run.target) + .contains(&CodegenBackendKind::Cranelift) + { builder.info("cranelift not in rust.codegen-backends. skipping"); return; } @@ -3607,7 +3611,7 @@ impl Step for CodegenGCC { return; } - if !builder.config.codegen_backends(run.target).contains(&CodegenBackendKind::Gcc) { + if !builder.config.enabled_codegen_backends(run.target).contains(&CodegenBackendKind::Gcc) { builder.info("gcc not in rust.codegen-backends. skipping"); return; } diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index f84565fccfddb..4351595ebee26 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -959,7 +959,8 @@ impl<'a> Builder<'a> { compile::Std, compile::Rustc, compile::Assemble, - compile::CodegenBackend, + compile::CraneliftCodegenBackend, + compile::GccCodegenBackend, compile::StartupObjects, tool::BuildManifest, tool::Rustbook, @@ -1150,7 +1151,7 @@ impl<'a> Builder<'a> { dist::JsonDocs, dist::Mingw, dist::Rustc, - dist::CodegenBackend, + dist::CraneliftCodegenBackend, dist::Std, dist::RustcDev, dist::Analysis, diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 139ddc9ed2496..178956eb6bbfa 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1290,6 +1290,40 @@ mod snapshot { "); } + // Enable dist cranelift tarball by default with `x dist` if cranelift is enabled in + // `rust.codegen-backends`. + #[test] + fn dist_cranelift_by_default() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx + .config("dist") + .args(&["--set", "rust.codegen-backends=['llvm', 'cranelift']"]) + .render_steps(), @r" + [build] rustc 0 -> UnstableBookGen 1 + [build] rustc 0 -> Rustbook 1 + [build] llvm + [build] rustc 0 -> rustc 1 + [build] rustc 0 -> rustc_codegen_cranelift 1 + [build] rustc 1 -> std 1 + [build] rustc 1 -> rustc 2 + [build] rustc 1 -> rustc_codegen_cranelift 2 + [build] rustdoc 2 + [doc] std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [build] rustc 2 -> std 2 + [build] rustc 0 -> LintDocs 1 + [build] rustc 0 -> RustInstaller 1 + [dist] docs + [doc] std 2 crates=[] + [dist] mingw + [build] rustc 0 -> GenerateCopyright 1 + [dist] rustc + [dist] rustc 1 -> rustc_codegen_cranelift 2 + [dist] rustc 1 -> std 1 + [dist] src <> + "); + } + #[test] fn check_compiler_no_explicit_stage() { let ctx = TestCtx::new(); diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 6055876c47579..5e367e3a8cd1a 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1747,19 +1747,24 @@ impl Config { .unwrap_or(self.profiler) } - pub fn codegen_backends(&self, target: TargetSelection) -> &[CodegenBackendKind] { + /// Returns codegen backends that should be: + /// - Built and added to the sysroot when we build the compiler. + /// - Distributed when `x dist` is executed (if the codegen backend has a dist step). + pub fn enabled_codegen_backends(&self, target: TargetSelection) -> &[CodegenBackendKind] { self.target_config .get(&target) .and_then(|cfg| cfg.codegen_backends.as_deref()) .unwrap_or(&self.rust_codegen_backends) } - pub fn jemalloc(&self, target: TargetSelection) -> bool { - self.target_config.get(&target).and_then(|cfg| cfg.jemalloc).unwrap_or(self.jemalloc) + /// Returns the codegen backend that should be configured as the *default* codegen backend + /// for a rustc compiled by bootstrap. + pub fn default_codegen_backend(&self, target: TargetSelection) -> Option { + self.enabled_codegen_backends(target).first().cloned() } - pub fn default_codegen_backend(&self, target: TargetSelection) -> Option { - self.codegen_backends(target).first().cloned() + pub fn jemalloc(&self, target: TargetSelection) -> bool { + self.target_config.get(&target).and_then(|cfg| cfg.jemalloc).unwrap_or(self.jemalloc) } pub fn rpath_enabled(&self, target: TargetSelection) -> bool { @@ -1774,7 +1779,7 @@ impl Config { } pub fn llvm_enabled(&self, target: TargetSelection) -> bool { - self.codegen_backends(target).contains(&CodegenBackendKind::Llvm) + self.enabled_codegen_backends(target).contains(&CodegenBackendKind::Llvm) } pub fn llvm_libunwind(&self, target: TargetSelection) -> LlvmLibunwind {