From ed7479c658484647858e08342a9aa00aa0fb5b30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 14 Jan 2026 21:47:24 +0100 Subject: [PATCH 1/4] Add the GCC codegen backend to build-manifest --- src/tools/build-manifest/src/main.rs | 3 ++- src/tools/build-manifest/src/versions.rs | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 4cec1b1f164b9..7c0c528bcc049 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -32,7 +32,7 @@ static DOCS_FALLBACK: &[(&str, &str)] = &[ static PKG_INSTALLERS: &[&str] = &["x86_64-apple-darwin", "aarch64-apple-darwin"]; static NIGHTLY_ONLY_COMPONENTS: &[PkgType] = - &[PkgType::Miri, PkgType::JsonDocs, PkgType::RustcCodegenCranelift]; + &[PkgType::Miri, PkgType::JsonDocs, PkgType::RustcCodegenCranelift, PkgType::RustcCodegenGcc]; macro_rules! t { ($e:expr) => { @@ -302,6 +302,7 @@ impl Builder { | PkgType::RustAnalysis | PkgType::JsonDocs | PkgType::RustcCodegenCranelift + | PkgType::RustcCodegenGcc | PkgType::LlvmBitcodeLinker => { extensions.push(host_component(pkg)); } diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs index 6ef8a0e83de3f..1e55d1d467e66 100644 --- a/src/tools/build-manifest/src/versions.rs +++ b/src/tools/build-manifest/src/versions.rs @@ -59,6 +59,7 @@ pkg_type! { JsonDocs = "rust-docs-json"; preview = true, RustcCodegenCranelift = "rustc-codegen-cranelift"; preview = true, LlvmBitcodeLinker = "llvm-bitcode-linker"; preview = true, + RustcCodegenGcc = "rustc-codegen-gcc"; preview = true, } impl PkgType { @@ -82,6 +83,7 @@ impl PkgType { PkgType::LlvmTools => false, PkgType::Miri => false, PkgType::RustcCodegenCranelift => false, + PkgType::RustcCodegenGcc => false, PkgType::Rust => true, PkgType::RustStd => true, @@ -111,6 +113,7 @@ impl PkgType { RustcDocs => HOSTS, Cargo => HOSTS, RustcCodegenCranelift => HOSTS, + RustcCodegenGcc => HOSTS, RustMingw => MINGW, RustStd => TARGETS, HtmlDocs => HOSTS, From 4ceb13807e8062d5a4a3e9adecbd1d42a61eecf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 14 Jan 2026 21:49:44 +0100 Subject: [PATCH 2/4] Forbid distributing GCC on CI if `gcc.download-ci-gcc` is enabled --- src/bootstrap/src/core/build_steps/dist.rs | 10 +++++++++- src/bootstrap/src/core/config/mod.rs | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index cfcb144e0993e..bfffc958f858c 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -30,7 +30,7 @@ use crate::core::build_steps::tool::{ use crate::core::build_steps::vendor::{VENDOR_DIR, Vendor}; use crate::core::build_steps::{compile, llvm}; use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step, StepMetadata}; -use crate::core::config::TargetSelection; +use crate::core::config::{GccCiMode, TargetSelection}; use crate::utils::build_stamp::{self, BuildStamp}; use crate::utils::channel::{self, Info}; use crate::utils::exec::{BootstrapCommand, command}; @@ -3035,6 +3035,14 @@ impl Step for Gcc { return None; } + if builder.config.is_running_on_ci { + assert_eq!( + builder.config.gcc_ci_mode, + GccCiMode::BuildLocally, + "Cannot use gcc.download-ci-gcc when distributing GCC on CI" + ); + } + // We need the GCC sources to build GCC and also to add its license and README // files to the tarball builder.require_submodule( diff --git a/src/bootstrap/src/core/config/mod.rs b/src/bootstrap/src/core/config/mod.rs index 007ed4aaba13f..7651def62672a 100644 --- a/src/bootstrap/src/core/config/mod.rs +++ b/src/bootstrap/src/core/config/mod.rs @@ -425,7 +425,7 @@ impl std::str::FromStr for RustcLto { } /// Determines how will GCC be provided. -#[derive(Default, Clone)] +#[derive(Default, Debug, Clone, PartialEq)] pub enum GccCiMode { /// Build GCC from the local `src/gcc` submodule. BuildLocally, From ea9b062a8a71d16f8327ddf7d9ceac405a9a3bdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 15 Jan 2026 11:15:26 +0100 Subject: [PATCH 3/4] Add GCC to build-manifest --- src/tools/build-manifest/src/main.rs | 7 +-- src/tools/build-manifest/src/versions.rs | 56 +++++++++++++++++++----- 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 7c0c528bcc049..cd6efad011411 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -158,7 +158,7 @@ impl Builder { } fn add_packages_to(&mut self, manifest: &mut Manifest) { - for pkg in PkgType::all() { + for pkg in &PkgType::all() { self.package(pkg, &mut manifest.pkg); } } @@ -227,7 +227,7 @@ impl Builder { }; for pkg in PkgType::all() { if pkg.is_preview() { - rename(pkg.tarball_component_name(), &pkg.manifest_component_name()); + rename(&pkg.tarball_component_name(), &pkg.manifest_component_name()); } } } @@ -263,7 +263,7 @@ impl Builder { let host_component = |pkg: &_| Component::from_pkg(pkg, host); - for pkg in PkgType::all() { + for pkg in &PkgType::all() { match pkg { // rustc/rust-std/cargo/docs are all required PkgType::Rustc | PkgType::Cargo | PkgType::HtmlDocs => { @@ -303,6 +303,7 @@ impl Builder { | PkgType::JsonDocs | PkgType::RustcCodegenCranelift | PkgType::RustcCodegenGcc + | PkgType::Gcc { .. } | PkgType::LlvmBitcodeLinker => { extensions.push(host_component(pkg)); } diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs index 1e55d1d467e66..b53f6c5edc5d9 100644 --- a/src/tools/build-manifest/src/versions.rs +++ b/src/tools/build-manifest/src/versions.rs @@ -11,29 +11,54 @@ use xz2::read::XzDecoder; const DEFAULT_TARGET: &str = "x86_64-unknown-linux-gnu"; macro_rules! pkg_type { - ( $($variant:ident = $component:literal $(; preview = true $(@$is_preview:tt)? )? ),+ $(,)? ) => { + ( $($variant:ident = $component:literal $(; preview = true $(@$is_preview:tt)? )? $(; suffixes = [$($suffixes:literal),+] $(@$is_suffixed:tt)? )? ),+ $(,)? ) => { #[derive(Debug, Hash, Eq, PartialEq, Clone)] pub(crate) enum PkgType { - $($variant,)+ + $($variant $( $($is_suffixed)? { suffix: &'static str })?,)+ } impl PkgType { pub(crate) fn is_preview(&self) -> bool { match self { - $( $( $($is_preview)? PkgType::$variant => true, )? )+ - _ => false, + $( PkgType::$variant $($($is_suffixed)? { .. })? => false $( $($is_preview)? || true)?, )+ } } - /// First part of the tarball name. - pub(crate) fn tarball_component_name(&self) -> &str { + /// First part of the tarball name. May include a suffix, if the package has one. + pub(crate) fn tarball_component_name(&self) -> String { match self { - $( PkgType::$variant => $component,)+ + $( PkgType::$variant $($($is_suffixed)? { suffix })? => { + #[allow(unused_mut)] + let mut name = $component.to_owned(); + $($($is_suffixed)? + name.push('-'); + name.push_str(suffix); + )? + name + },)+ } } - pub(crate) fn all() -> &'static [PkgType] { - &[ $(PkgType::$variant),+ ] + pub(crate) fn all() -> Vec { + let mut packages = vec![]; + $( + // Push the single variant + packages.push(PkgType::$variant $($($is_suffixed)? { suffix: "" })?); + // Macro hell, we have to remove the fake empty suffix if we actually have + // suffixes + $( + $($is_suffixed)? + packages.pop(); + )? + // And now add the suffixes, if any + $( + $($is_suffixed)? + $( + packages.push(PkgType::$variant { suffix: $suffixes }); + )+ + )? + )+ + packages } } } @@ -60,6 +85,9 @@ pkg_type! { RustcCodegenCranelift = "rustc-codegen-cranelift"; preview = true, LlvmBitcodeLinker = "llvm-bitcode-linker"; preview = true, RustcCodegenGcc = "rustc-codegen-gcc"; preview = true, + Gcc = "gcc"; preview = true; suffixes = [ + "x86_64-unknown-linux-gnu" + ], } impl PkgType { @@ -68,7 +96,7 @@ impl PkgType { if self.is_preview() { format!("{}-preview", self.tarball_component_name()) } else { - self.tarball_component_name().to_string() + self.tarball_component_name() } } @@ -84,6 +112,7 @@ impl PkgType { PkgType::Miri => false, PkgType::RustcCodegenCranelift => false, PkgType::RustcCodegenGcc => false, + PkgType::Gcc { suffix: _ } => false, PkgType::Rust => true, PkgType::RustStd => true, @@ -114,6 +143,13 @@ impl PkgType { Cargo => HOSTS, RustcCodegenCranelift => HOSTS, RustcCodegenGcc => HOSTS, + // Gcc is "special", because we need a separate libgccjit.so for each + // (host, target) compilation pair. So it's even more special than stdlib, which has a + // separate component per target. This component thus hardcodes its compilation + // target in its name, and we thus ship it for HOSTS only. So we essentially have + // gcc-T1, gcc-T2, a separate *component/package* per each compilation target. + // So on host T1, if you want to compile for T2, you would install gcc-T2. + Gcc { suffix: _ } => HOSTS, RustMingw => MINGW, RustStd => TARGETS, HtmlDocs => HOSTS, From f4834cf52e38ffac51d1a2a6d47257013c4e84d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 21 Jan 2026 09:44:18 +0100 Subject: [PATCH 4/4] Make the GCC component as nightly only in build-manifest --- src/tools/build-manifest/src/main.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index cd6efad011411..946962832aef4 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -31,8 +31,16 @@ static DOCS_FALLBACK: &[(&str, &str)] = &[ static PKG_INSTALLERS: &[&str] = &["x86_64-apple-darwin", "aarch64-apple-darwin"]; -static NIGHTLY_ONLY_COMPONENTS: &[PkgType] = - &[PkgType::Miri, PkgType::JsonDocs, PkgType::RustcCodegenCranelift, PkgType::RustcCodegenGcc]; +fn is_nightly_only(pkg: &PkgType) -> bool { + match pkg { + PkgType::Miri + | PkgType::JsonDocs + | PkgType::RustcCodegenCranelift + | PkgType::RustcCodegenGcc + | PkgType::Gcc { .. } => true, + _ => false, + } +} macro_rules! t { ($e:expr) => { @@ -375,7 +383,7 @@ impl Builder { let mut is_present = version_info.present; // Never ship nightly-only components for other trains. - if self.versions.channel() != "nightly" && NIGHTLY_ONLY_COMPONENTS.contains(&pkg) { + if self.versions.channel() != "nightly" && is_nightly_only(&pkg) { is_present = false; // Pretend the component is entirely missing. }