Skip to content

Commit c1d67ef

Browse files
committed
Refactor *.optimized-compiler-builtins bootstrap options
Create a dedicated enum to abstract the different ways compiler-builtins can be configured. This also relaxes build.optimized-compiler-builtins to accept the path of a library to match the behavior of <target>.optimized-compiler-builtins override.
1 parent 9db5dcd commit c1d67ef

File tree

9 files changed

+71
-36
lines changed

9 files changed

+71
-36
lines changed

bootstrap.example.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,8 +407,11 @@
407407
#build.profiler = false
408408

409409
# Use the optimized LLVM C intrinsics for `compiler_builtins`, rather than Rust intrinsics.
410-
# Requires the LLVM submodule to be managed by bootstrap (i.e. not external) so that `compiler-rt`
411-
# sources are available.
410+
# Choosing true requires the LLVM submodule to be managed by bootstrap (i.e. not external)
411+
# so that `compiler-rt` sources are available.
412+
#
413+
# Setting this to a path removes the requirement for a C toolchain, but requires setting the
414+
# path to an existing library containing the builtins library from LLVM's compiler-rt.
412415
#
413416
# Setting this to `false` generates slower code, but removes the requirement for a C toolchain in
414417
# order to run `x check`.

src/bootstrap/src/core/build_steps/compile.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ use crate::core::builder;
2626
use crate::core::builder::{
2727
Builder, Cargo, Kind, RunConfig, ShouldRun, Step, StepMetadata, crate_description,
2828
};
29-
use crate::core::config::{DebuginfoLevel, LlvmLibunwind, RustcLto, TargetSelection};
29+
use crate::core::config::{
30+
CompilerBuiltins, DebuginfoLevel, LlvmLibunwind, RustcLto, TargetSelection,
31+
};
3032
use crate::utils::build_stamp;
3133
use crate::utils::build_stamp::BuildStamp;
3234
use crate::utils::exec::command;
@@ -560,10 +562,12 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, cargo: &mut Car
560562
// If `compiler-rt` is available ensure that the `c` feature of the
561563
// `compiler-builtins` crate is enabled and it's configured to learn where
562564
// `compiler-rt` is located.
563-
let compiler_builtins_c_feature = if builder.config.optimized_compiler_builtins(target) {
564-
if let Some(path) = builder.config.optimized_compiler_builtins_path(target) {
565+
let compiler_builtins_c_feature = match builder.config.optimized_compiler_builtins(target) {
566+
CompilerBuiltins::LinkLLVMBuiltinsLib(path) => {
565567
cargo.env("LLVM_COMPILER_RT_LIB", path);
566-
} else {
568+
" compiler-builtins-c"
569+
}
570+
CompilerBuiltins::BuildLLVMFuncs => {
567571
// NOTE: this interacts strangely with `llvm-has-rust-patches`. In that case, we enforce
568572
// `submodules = false`, so this is a no-op. But, the user could still decide to
569573
// manually use an in-tree submodule.
@@ -585,10 +589,9 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, cargo: &mut Car
585589
// The path to `compiler-rt` is also used by `profiler_builtins` (above),
586590
// so if you're changing something here please also change that as appropriate.
587591
cargo.env("RUST_COMPILER_RT_ROOT", &compiler_builtins_root);
592+
" compiler-builtins-c"
588593
}
589-
" compiler-builtins-c"
590-
} else {
591-
""
594+
CompilerBuiltins::BuildRustOnly => "",
592595
};
593596

594597
// `libtest` uses this to know whether or not to support

src/bootstrap/src/core/config/config.rs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ use crate::core::config::toml::rust::{
4646
};
4747
use crate::core::config::toml::target::Target;
4848
use crate::core::config::{
49-
DebuginfoLevel, DryRun, GccCiMode, LlvmLibunwind, Merge, ReplaceOpt, RustcLto, SplitDebuginfo,
50-
StringOrBool, threads_from_config,
49+
CompilerBuiltins, DebuginfoLevel, DryRun, GccCiMode, LlvmLibunwind, Merge, ReplaceOpt,
50+
RustcLto, SplitDebuginfo, StringOrBool, threads_from_config,
5151
};
5252
use crate::core::download::{
5353
DownloadContext, download_beta_toolchain, is_download_ci_available, maybe_download_rustfmt,
@@ -121,8 +121,7 @@ pub struct Config {
121121
pub patch_binaries_for_nix: Option<bool>,
122122
pub stage0_metadata: build_helper::stage0_parser::Stage0,
123123
pub android_ndk: Option<PathBuf>,
124-
/// Whether to use the `c` feature of the `compiler_builtins` crate.
125-
pub optimized_compiler_builtins: bool,
124+
pub optimized_compiler_builtins: CompilerBuiltins,
126125

127126
pub stdout_is_tty: bool,
128127
pub stderr_is_tty: bool,
@@ -1101,7 +1100,11 @@ impl Config {
11011100
let rustfmt_info = git_info(&exec_ctx, omit_git_hash, &src.join("src/tools/rustfmt"));
11021101

11031102
let optimized_compiler_builtins =
1104-
build_optimized_compiler_builtins.unwrap_or(channel != "dev");
1103+
build_optimized_compiler_builtins.unwrap_or(if channel == "dev" {
1104+
CompilerBuiltins::BuildRustOnly
1105+
} else {
1106+
CompilerBuiltins::BuildLLVMFuncs
1107+
});
11051108
let vendor = build_vendor.unwrap_or(
11061109
rust_info.is_from_tarball()
11071110
&& src.join("vendor").exists()
@@ -1664,19 +1667,11 @@ impl Config {
16641667
self.target_config.get(&target).and_then(|t| t.rpath).unwrap_or(self.rust_rpath)
16651668
}
16661669

1667-
pub fn optimized_compiler_builtins(&self, target: TargetSelection) -> bool {
1670+
pub fn optimized_compiler_builtins(&self, target: TargetSelection) -> &CompilerBuiltins {
16681671
self.target_config
16691672
.get(&target)
16701673
.and_then(|t| t.optimized_compiler_builtins.as_ref())
1671-
.map(StringOrBool::is_string_or_true)
1672-
.unwrap_or(self.optimized_compiler_builtins)
1673-
}
1674-
1675-
pub fn optimized_compiler_builtins_path(&self, target: TargetSelection) -> Option<&str> {
1676-
match self.target_config.get(&target)?.optimized_compiler_builtins.as_ref()? {
1677-
StringOrBool::String(s) => Some(s),
1678-
StringOrBool::Bool(_) => None,
1679-
}
1674+
.unwrap_or(&self.optimized_compiler_builtins)
16801675
}
16811676

16821677
pub fn llvm_enabled(&self, target: TargetSelection) -> bool {

src/bootstrap/src/core/config/mod.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,33 @@ impl<T> Merge for Option<T> {
218218
}
219219
}
220220

221+
#[derive(Clone, Debug, Default, Eq, PartialEq)]
222+
pub enum CompilerBuiltins {
223+
#[default]
224+
// Only build native rust intrinsic compiler functions.
225+
BuildRustOnly,
226+
// Some intrinsic functions have a C implementation provided by LLVM's
227+
// compiler-rt builtins library. Build them from the LLVM source included
228+
// with Rust.
229+
BuildLLVMFuncs,
230+
// Similar to BuildLLVMFuncs, but specify a path to an existing library
231+
// containing LLVM's compiler-rt builtins instead of compiling them.
232+
LinkLLVMBuiltinsLib(String),
233+
}
234+
235+
impl<'de> Deserialize<'de> for CompilerBuiltins {
236+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
237+
where
238+
D: Deserializer<'de>,
239+
{
240+
Ok(match Deserialize::deserialize(deserializer)? {
241+
StringOrBool::Bool(false) => Self::BuildRustOnly,
242+
StringOrBool::Bool(true) => Self::BuildLLVMFuncs,
243+
StringOrBool::String(path) => Self::LinkLLVMBuiltinsLib(path),
244+
})
245+
}
246+
}
247+
221248
#[derive(Copy, Clone, Default, Debug, Eq, PartialEq)]
222249
pub enum DebuginfoLevel {
223250
#[default]

src/bootstrap/src/core/config/tests.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::core::build_steps::clippy::{LintConfig, get_clippy_rules_in_order};
1717
use crate::core::build_steps::llvm;
1818
use crate::core::build_steps::llvm::LLVM_INVALIDATION_PATHS;
1919
use crate::core::config::toml::TomlConfig;
20-
use crate::core::config::{LldMode, StringOrBool, Target, TargetSelection};
20+
use crate::core::config::{CompilerBuiltins, LldMode, StringOrBool, Target, TargetSelection};
2121
use crate::utils::tests::git::git_test;
2222

2323
pub(crate) fn parse(config: &str) -> Config {
@@ -183,7 +183,11 @@ runner = "x86_64-runner"
183183
);
184184
assert_eq!(config.gdb, Some("bar".into()), "setting string value with quotes");
185185
assert!(!config.deny_warnings, "setting boolean value");
186-
assert!(config.optimized_compiler_builtins, "setting boolean value");
186+
assert_eq!(
187+
config.optimized_compiler_builtins,
188+
CompilerBuiltins::BuildLLVMFuncs,
189+
"setting boolean value"
190+
);
187191
assert_eq!(
188192
config.tools,
189193
Some(["cargo".to_string()].into_iter().collect()),
@@ -212,7 +216,7 @@ runner = "x86_64-runner"
212216
let darwin = TargetSelection::from_user("aarch64-apple-darwin");
213217
let darwin_values = Target {
214218
runner: Some("apple".into()),
215-
optimized_compiler_builtins: Some(StringOrBool::Bool(false)),
219+
optimized_compiler_builtins: Some(CompilerBuiltins::BuildRustOnly),
216220
..Default::default()
217221
};
218222
assert_eq!(

src/bootstrap/src/core/config/toml/build.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::collections::HashMap;
1111
use serde::{Deserialize, Deserializer};
1212

1313
use crate::core::config::toml::ReplaceOpt;
14-
use crate::core::config::{Merge, StringOrBool};
14+
use crate::core::config::{CompilerBuiltins, Merge, StringOrBool};
1515
use crate::{HashSet, PathBuf, define_config, exit};
1616

1717
define_config! {
@@ -65,7 +65,7 @@ define_config! {
6565
// NOTE: only parsed by bootstrap.py, `--feature build-metrics` enables metrics unconditionally
6666
metrics: Option<bool> = "metrics",
6767
android_ndk: Option<PathBuf> = "android-ndk",
68-
optimized_compiler_builtins: Option<bool> = "optimized-compiler-builtins",
68+
optimized_compiler_builtins: Option<CompilerBuiltins> = "optimized-compiler-builtins",
6969
jobs: Option<u32> = "jobs",
7070
compiletest_diff_tool: Option<String> = "compiletest-diff-tool",
7171
compiletest_allow_stage0: Option<bool> = "compiletest-allow-stage0",

src/bootstrap/src/core/config/toml/rust.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,9 @@ pub fn check_incompatible_options_for_ci_rustc(
269269
err!(current_profiler, profiler, "build");
270270

271271
let current_optimized_compiler_builtins =
272-
current_config_toml.build.as_ref().and_then(|b| b.optimized_compiler_builtins);
272+
current_config_toml.build.as_ref().and_then(|b| b.optimized_compiler_builtins.clone());
273273
let optimized_compiler_builtins =
274-
ci_config_toml.build.as_ref().and_then(|b| b.optimized_compiler_builtins);
274+
ci_config_toml.build.as_ref().and_then(|b| b.optimized_compiler_builtins.clone());
275275
err!(current_optimized_compiler_builtins, optimized_compiler_builtins, "build");
276276

277277
// We always build the in-tree compiler on cross targets, so we only care

src/bootstrap/src/core/config/toml/target.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
1212
use serde::{Deserialize, Deserializer};
1313

14-
use crate::core::config::{LlvmLibunwind, Merge, ReplaceOpt, SplitDebuginfo, StringOrBool};
14+
use crate::core::config::{
15+
CompilerBuiltins, LlvmLibunwind, Merge, ReplaceOpt, SplitDebuginfo, StringOrBool,
16+
};
1517
use crate::{CodegenBackendKind, HashSet, PathBuf, define_config, exit};
1618

1719
define_config! {
@@ -39,7 +41,7 @@ define_config! {
3941
no_std: Option<bool> = "no-std",
4042
codegen_backends: Option<Vec<String>> = "codegen-backends",
4143
runner: Option<String> = "runner",
42-
optimized_compiler_builtins: Option<StringOrBool> = "optimized-compiler-builtins",
44+
optimized_compiler_builtins: Option<CompilerBuiltins> = "optimized-compiler-builtins",
4345
jemalloc: Option<bool> = "jemalloc",
4446
}
4547
}
@@ -71,7 +73,7 @@ pub struct Target {
7173
pub runner: Option<String>,
7274
pub no_std: bool,
7375
pub codegen_backends: Option<Vec<CodegenBackendKind>>,
74-
pub optimized_compiler_builtins: Option<StringOrBool>,
76+
pub optimized_compiler_builtins: Option<CompilerBuiltins>,
7577
pub jemalloc: Option<bool>,
7678
}
7779

src/bootstrap/src/core/sanity.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::builder::Builder;
1818
use crate::builder::Kind;
1919
#[cfg(not(test))]
2020
use crate::core::build_steps::tool;
21-
use crate::core::config::Target;
21+
use crate::core::config::{CompilerBuiltins, Target};
2222
use crate::utils::exec::command;
2323
use crate::{Build, Subcommand};
2424

@@ -330,7 +330,8 @@ than building it.
330330

331331
// compiler-rt c fallbacks for wasm cannot be built with gcc
332332
if target.contains("wasm")
333-
&& (build.config.optimized_compiler_builtins(*target)
333+
&& (*build.config.optimized_compiler_builtins(*target)
334+
!= CompilerBuiltins::BuildRustOnly
334335
|| build.config.rust_std_features.contains("compiler-builtins-c"))
335336
{
336337
let cc_tool = build.cc_tool(*target);

0 commit comments

Comments
 (0)