From 64cbe52849fdfb9ff097dd311be826b00d27ba45 Mon Sep 17 00:00:00 2001 From: Paul Murphy Date: Tue, 24 Jun 2025 11:07:54 -0500 Subject: Allow linking a prebuilt optimized compiler-rt builtins library Extend the .optimized-compiler-builtins bootstrap option to accept a path to a prebuilt compiler-rt builtins library, and update compiler-builtins to enable optimized builtins without building compiler-rt builtins. --- src/bootstrap/src/core/build_steps/compile.rs | 44 +++++++++++++++------------ src/bootstrap/src/core/config/config.rs | 10 +++++- src/bootstrap/src/core/config/tests.rs | 4 +-- src/bootstrap/src/core/config/toml/target.rs | 4 +-- src/bootstrap/src/utils/change_tracker.rs | 5 +++ 5 files changed, 43 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 8cad5b920b9..005c849c47a 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -575,25 +575,31 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, cargo: &mut Car // `compiler-builtins` crate is enabled and it's configured to learn where // `compiler-rt` is located. let compiler_builtins_c_feature = if builder.config.optimized_compiler_builtins(target) { - // NOTE: this interacts strangely with `llvm-has-rust-patches`. In that case, we enforce `submodules = false`, so this is a no-op. - // But, the user could still decide to manually use an in-tree submodule. - // - // NOTE: if we're using system llvm, we'll end up building a version of `compiler-rt` that doesn't match the LLVM we're linking to. - // That's probably ok? At least, the difference wasn't enforced before. There's a comment in - // the compiler_builtins build script that makes me nervous, though: - // https://github.com/rust-lang/compiler-builtins/blob/31ee4544dbe47903ce771270d6e3bea8654e9e50/build.rs#L575-L579 - builder.require_submodule( - "src/llvm-project", - Some( - "The `build.optimized-compiler-builtins` config option \ - requires `compiler-rt` sources from LLVM.", - ), - ); - let compiler_builtins_root = builder.src.join("src/llvm-project/compiler-rt"); - assert!(compiler_builtins_root.exists()); - // The path to `compiler-rt` is also used by `profiler_builtins` (above), - // so if you're changing something here please also change that as appropriate. - cargo.env("RUST_COMPILER_RT_ROOT", &compiler_builtins_root); + if let Some(path) = builder.config.optimized_compiler_builtins_path(target) { + cargo.env("LLVM_COMPILER_RT_LIB", path); + } else { + // NOTE: this interacts strangely with `llvm-has-rust-patches`. In that case, we enforce + // `submodules = false`, so this is a no-op. But, the user could still decide to + // manually use an in-tree submodule. + // + // NOTE: if we're using system llvm, we'll end up building a version of `compiler-rt` + // that doesn't match the LLVM we're linking to. That's probably ok? At least, the + // difference wasn't enforced before. There's a comment in the compiler_builtins build + // script that makes me nervous, though: + // https://github.com/rust-lang/compiler-builtins/blob/31ee4544dbe47903ce771270d6e3bea8654e9e50/build.rs#L575-L579 + builder.require_submodule( + "src/llvm-project", + Some( + "The `build.optimized-compiler-builtins` config option \ + requires `compiler-rt` sources from LLVM.", + ), + ); + let compiler_builtins_root = builder.src.join("src/llvm-project/compiler-rt"); + assert!(compiler_builtins_root.exists()); + // The path to `compiler-rt` is also used by `profiler_builtins` (above), + // so if you're changing something here please also change that as appropriate. + cargo.env("RUST_COMPILER_RT_ROOT", &compiler_builtins_root); + } " compiler-builtins-c" } else { "" diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 05c2579ac08..09a1eb5b847 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1675,10 +1675,18 @@ impl Config { pub fn optimized_compiler_builtins(&self, target: TargetSelection) -> bool { self.target_config .get(&target) - .and_then(|t| t.optimized_compiler_builtins) + .and_then(|t| t.optimized_compiler_builtins.as_ref()) + .map(StringOrBool::is_string_or_true) .unwrap_or(self.optimized_compiler_builtins) } + pub fn optimized_compiler_builtins_path(&self, target: TargetSelection) -> Option<&str> { + match self.target_config.get(&target)?.optimized_compiler_builtins.as_ref()? { + StringOrBool::String(s) => Some(s), + StringOrBool::Bool(_) => None, + } + } + pub fn llvm_enabled(&self, target: TargetSelection) -> bool { self.enabled_codegen_backends(target).contains(&CodegenBackendKind::Llvm) } diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs index 50eba12aba7..c32e4384cf6 100644 --- a/src/bootstrap/src/core/config/tests.rs +++ b/src/bootstrap/src/core/config/tests.rs @@ -17,7 +17,7 @@ use crate::core::build_steps::clippy::{LintConfig, get_clippy_rules_in_order}; use crate::core::build_steps::llvm; use crate::core::build_steps::llvm::LLVM_INVALIDATION_PATHS; use crate::core::config::toml::TomlConfig; -use crate::core::config::{LldMode, Target, TargetSelection}; +use crate::core::config::{LldMode, StringOrBool, Target, TargetSelection}; use crate::utils::tests::git::git_test; pub(crate) fn parse(config: &str) -> Config { @@ -212,7 +212,7 @@ runner = "x86_64-runner" let darwin = TargetSelection::from_user("aarch64-apple-darwin"); let darwin_values = Target { runner: Some("apple".into()), - optimized_compiler_builtins: Some(false), + optimized_compiler_builtins: Some(StringOrBool::Bool(false)), ..Default::default() }; assert_eq!( diff --git a/src/bootstrap/src/core/config/toml/target.rs b/src/bootstrap/src/core/config/toml/target.rs index 2c06fd083a8..3236b5cdbaa 100644 --- a/src/bootstrap/src/core/config/toml/target.rs +++ b/src/bootstrap/src/core/config/toml/target.rs @@ -39,7 +39,7 @@ define_config! { no_std: Option = "no-std", codegen_backends: Option> = "codegen-backends", runner: Option = "runner", - optimized_compiler_builtins: Option = "optimized-compiler-builtins", + optimized_compiler_builtins: Option = "optimized-compiler-builtins", jemalloc: Option = "jemalloc", } } @@ -71,7 +71,7 @@ pub struct Target { pub runner: Option, pub no_std: bool, pub codegen_backends: Option>, - pub optimized_compiler_builtins: Option, + pub optimized_compiler_builtins: Option, pub jemalloc: Option, } diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 54f563fe68c..073954e9337 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -521,4 +521,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Warning, summary: "It is no longer possible to `x dist` or `x install` with stage 0. All dist and install commands have to be on stage 1+.", }, + ChangeInfo { + change_id: 143689, + severity: ChangeSeverity::Info, + summary: "The `optimized-compiler-builtins` option now accepts a path to an existing compiler-rt builtins library.", + }, ]; -- cgit 1.4.1-3-g733a5