Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions bootstrap.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -768,16 +768,15 @@
# make this default to false.
#rust.lld = false in all cases, except on `x86_64-unknown-linux-gnu` as described above, where it is true

# Indicates whether LLD will be used to link Rust crates during bootstrap on
# supported platforms.
# Indicates if we should override the linker used to link Rust crates during bootstrap to be LLD.
# If set to `true` or `"external"`, a global `lld` binary that has to be in $PATH
# will be used.
# If set to `"self-contained"`, rust-lld from the snapshot compiler will be used.
#
# On MSVC, LLD will not be used if we're cross linking.
#
# Explicitly setting the linker for a target will override this option when targeting MSVC.
#rust.use-lld = false
#rust.bootstrap-override-lld = false

# Indicates whether some LLVM tools, like llvm-objdump, will be made available in the
# sysroot.
Expand Down Expand Up @@ -950,7 +949,7 @@
# Linker to be used to bootstrap Rust code. Note that the
# default value is platform specific, and if not specified it may also depend on
# what platform is crossing to what platform.
# Setting this will override the `use-lld` option for Rust code when targeting MSVC.
# Setting this will override the `bootstrap-override-lld` option for Rust code when targeting MSVC.
#linker = "cc" (path)

# Should rustc and the standard library be built with split debuginfo? Default
Expand Down
4 changes: 2 additions & 2 deletions src/bootstrap/src/core/build_steps/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1219,7 +1219,7 @@ pub fn rustc_cargo(
// us a faster startup time. However GNU ld < 2.40 will error if we try to link a shared object
// with direct references to protected symbols, so for now we only use protected symbols if
// linking with LLD is enabled.
if builder.build.config.lld_mode.is_used() {
if builder.build.config.bootstrap_override_lld.is_used() {
cargo.rustflag("-Zdefault-visibility=protected");
}

Expand Down Expand Up @@ -1256,7 +1256,7 @@ pub fn rustc_cargo(
// is already on by default in MSVC optimized builds, which is interpreted as --icf=all:
// https://github.com/llvm/llvm-project/blob/3329cec2f79185bafd678f310fafadba2a8c76d2/lld/COFF/Driver.cpp#L1746
// https://github.com/rust-lang/rust/blob/f22819bcce4abaff7d1246a56eec493418f9f4ee/compiler/rustc_codegen_ssa/src/back/linker.rs#L827
if builder.config.lld_mode.is_used() && !build_compiler.host.is_msvc() {
if builder.config.bootstrap_override_lld.is_used() && !build_compiler.host.is_msvc() {
cargo.rustflag("-Clink-args=-Wl,--icf=all");
}

Expand Down
20 changes: 15 additions & 5 deletions src/bootstrap/src/core/config/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use crate::core::config::toml::gcc::Gcc;
use crate::core::config::toml::install::Install;
use crate::core::config::toml::llvm::Llvm;
use crate::core::config::toml::rust::{
LldMode, Rust, RustOptimize, check_incompatible_options_for_ci_rustc,
BootstrapOverrideLld, Rust, RustOptimize, check_incompatible_options_for_ci_rustc,
default_lld_opt_in_targets, parse_codegen_backends,
};
use crate::core::config::toml::target::Target;
Expand Down Expand Up @@ -174,7 +174,7 @@ pub struct Config {
pub llvm_from_ci: bool,
pub llvm_build_config: HashMap<String, String>,

pub lld_mode: LldMode,
pub bootstrap_override_lld: BootstrapOverrideLld,
pub lld_enabled: bool,
pub llvm_tools_enabled: bool,
pub llvm_bitcode_linker_enabled: bool,
Expand Down Expand Up @@ -567,7 +567,8 @@ impl Config {
frame_pointers: rust_frame_pointers,
stack_protector: rust_stack_protector,
strip: rust_strip,
lld_mode: rust_lld_mode,
bootstrap_override_lld: rust_bootstrap_override_lld,
bootstrap_override_lld_legacy: rust_bootstrap_override_lld_legacy,
std_features: rust_std_features,
break_on_ice: rust_break_on_ice,
} = toml.rust.unwrap_or_default();
Expand Down Expand Up @@ -615,6 +616,15 @@ impl Config {

let Gcc { download_ci_gcc: gcc_download_ci_gcc } = toml.gcc.unwrap_or_default();

if rust_bootstrap_override_lld.is_some() && rust_bootstrap_override_lld_legacy.is_some() {
panic!(
"Cannot use both `rust.use-lld` and `rust.bootstrap-override-lld`. Please use only `rust.bootstrap-override-lld`"
);
}

let bootstrap_override_lld =
rust_bootstrap_override_lld.or(rust_bootstrap_override_lld_legacy).unwrap_or_default();

if rust_optimize.as_ref().is_some_and(|v| matches!(v, RustOptimize::Bool(false))) {
eprintln!(
"WARNING: setting `optimize` to `false` is known to cause errors and \
Expand Down Expand Up @@ -960,7 +970,7 @@ impl Config {

let initial_rustfmt = build_rustfmt.or_else(|| maybe_download_rustfmt(&dwn_ctx, &out));

if matches!(rust_lld_mode.unwrap_or_default(), LldMode::SelfContained)
if matches!(bootstrap_override_lld, BootstrapOverrideLld::SelfContained)
&& !lld_enabled
&& flags_stage.unwrap_or(0) > 0
{
Expand Down Expand Up @@ -1172,6 +1182,7 @@ impl Config {
backtrace_on_ice: rust_backtrace_on_ice.unwrap_or(false),
bindir: install_bindir.map(PathBuf::from).unwrap_or("bin".into()),
bootstrap_cache_path: build_bootstrap_cache_path,
bootstrap_override_lld,
bypass_bootstrap_lock: flags_bypass_bootstrap_lock,
cargo_info,
cargo_native_static: build_cargo_native_static.unwrap_or(false),
Expand Down Expand Up @@ -1238,7 +1249,6 @@ impl Config {
libdir: install_libdir.map(PathBuf::from),
library_docs_private_items: build_library_docs_private_items.unwrap_or(false),
lld_enabled,
lld_mode: rust_lld_mode.unwrap_or_default(),
lldb: build_lldb.map(PathBuf::from),
llvm_allow_old_toolchain: llvm_allow_old_toolchain.unwrap_or(false),
llvm_assertions,
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/src/core/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use serde_derive::Deserialize;
pub use target_selection::TargetSelection;
pub use toml::BUILDER_CONFIG_FILENAME;
pub use toml::change_id::ChangeId;
pub use toml::rust::LldMode;
pub use toml::rust::BootstrapOverrideLld;
pub use toml::target::Target;

use crate::Display;
Expand Down
36 changes: 30 additions & 6 deletions src/bootstrap/src/core/config/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ use crate::core::build_steps::clippy::{LintConfig, get_clippy_rules_in_order};
use crate::core::build_steps::llvm::LLVM_INVALIDATION_PATHS;
use crate::core::build_steps::{llvm, test};
use crate::core::config::toml::TomlConfig;
use crate::core::config::{CompilerBuiltins, LldMode, StringOrBool, Target, TargetSelection};
use crate::core::config::{
BootstrapOverrideLld, CompilerBuiltins, StringOrBool, Target, TargetSelection,
};
use crate::utils::tests::TestCtx;
use crate::utils::tests::git::git_test;

Expand Down Expand Up @@ -222,11 +224,33 @@ fn verify_file_integrity() {

#[test]
fn rust_lld() {
assert!(matches!(parse("").lld_mode, LldMode::Unused));
assert!(matches!(parse("rust.use-lld = \"self-contained\"").lld_mode, LldMode::SelfContained));
assert!(matches!(parse("rust.use-lld = \"external\"").lld_mode, LldMode::External));
assert!(matches!(parse("rust.use-lld = true").lld_mode, LldMode::External));
assert!(matches!(parse("rust.use-lld = false").lld_mode, LldMode::Unused));
assert!(matches!(parse("").bootstrap_override_lld, BootstrapOverrideLld::None));
assert!(matches!(
parse("rust.bootstrap-override-lld = \"self-contained\"").bootstrap_override_lld,
BootstrapOverrideLld::SelfContained
));
assert!(matches!(
parse("rust.bootstrap-override-lld = \"external\"").bootstrap_override_lld,
BootstrapOverrideLld::External
));
assert!(matches!(
parse("rust.bootstrap-override-lld = true").bootstrap_override_lld,
BootstrapOverrideLld::External
));
assert!(matches!(
parse("rust.bootstrap-override-lld = false").bootstrap_override_lld,
BootstrapOverrideLld::None
));

// Also check the legacy options
assert!(matches!(
parse("rust.use-lld = true").bootstrap_override_lld,
BootstrapOverrideLld::External
));
assert!(matches!(
parse("rust.use-lld = false").bootstrap_override_lld,
BootstrapOverrideLld::None
));
}

#[test]
Expand Down
49 changes: 31 additions & 18 deletions src/bootstrap/src/core/config/toml/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ define_config! {
codegen_backends: Option<Vec<String>> = "codegen-backends",
llvm_bitcode_linker: Option<bool> = "llvm-bitcode-linker",
lld: Option<bool> = "lld",
lld_mode: Option<LldMode> = "use-lld",
bootstrap_override_lld: Option<BootstrapOverrideLld> = "bootstrap-override-lld",
// FIXME: Remove this option in Spring 2026
bootstrap_override_lld_legacy: Option<BootstrapOverrideLld> = "use-lld",
llvm_tools: Option<bool> = "llvm-tools",
deny_warnings: Option<bool> = "deny-warnings",
backtrace_on_ice: Option<bool> = "backtrace-on-ice",
Expand All @@ -70,22 +72,33 @@ define_config! {
}
}

/// LLD in bootstrap works like this:
/// - Self-contained lld: use `rust-lld` from the compiler's sysroot
/// Determines if we should override the linker used for linking Rust code built
/// during the bootstrapping process to be LLD.
///
/// The primary use-case for this is to make local (re)builds of Rust code faster
/// when using bootstrap.
///
/// This does not affect the *behavior* of the built/distributed compiler when invoked
/// outside of bootstrap.
/// It might affect its performance/binary size though, as that can depend on the
/// linker that links rustc.
///
/// There are two ways of overriding the linker to be LLD:
/// - Self-contained LLD: use `rust-lld` from the compiler's sysroot
/// - External: use an external `lld` binary
///
/// It is configured depending on the target:
/// 1) Everything except MSVC
/// - Self-contained: `-Clinker-flavor=gnu-lld-cc -Clink-self-contained=+linker`
/// - External: `-Clinker-flavor=gnu-lld-cc`
/// - Self-contained: `-Clinker-features=+lld -Clink-self-contained=+linker`
/// - External: `-Clinker-features=+lld`
/// 2) MSVC
/// - Self-contained: `-Clinker=<path to rust-lld>`
/// - External: `-Clinker=lld`
#[derive(Copy, Clone, Default, Debug, PartialEq)]
pub enum LldMode {
/// Do not use LLD
pub enum BootstrapOverrideLld {
/// Do not override the linker LLD
#[default]
Unused,
None,
/// Use `rust-lld` from the compiler's sysroot
SelfContained,
/// Use an externally provided `lld` binary.
Expand All @@ -94,24 +107,24 @@ pub enum LldMode {
External,
}

impl LldMode {
impl BootstrapOverrideLld {
pub fn is_used(&self) -> bool {
match self {
LldMode::SelfContained | LldMode::External => true,
LldMode::Unused => false,
BootstrapOverrideLld::SelfContained | BootstrapOverrideLld::External => true,
BootstrapOverrideLld::None => false,
}
}
}

impl<'de> Deserialize<'de> for LldMode {
impl<'de> Deserialize<'de> for BootstrapOverrideLld {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct LldModeVisitor;

impl serde::de::Visitor<'_> for LldModeVisitor {
type Value = LldMode;
type Value = BootstrapOverrideLld;

fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str("one of true, 'self-contained' or 'external'")
Expand All @@ -121,16 +134,16 @@ impl<'de> Deserialize<'de> for LldMode {
where
E: serde::de::Error,
{
Ok(if v { LldMode::External } else { LldMode::Unused })
Ok(if v { BootstrapOverrideLld::External } else { BootstrapOverrideLld::None })
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
match v {
"external" => Ok(LldMode::External),
"self-contained" => Ok(LldMode::SelfContained),
"external" => Ok(BootstrapOverrideLld::External),
"self-contained" => Ok(BootstrapOverrideLld::SelfContained),
_ => Err(E::custom(format!("unknown mode {v}"))),
}
}
Expand Down Expand Up @@ -311,7 +324,6 @@ pub fn check_incompatible_options_for_ci_rustc(
lto,
stack_protector,
strip,
lld_mode,
jemalloc,
rpath,
channel,
Expand Down Expand Up @@ -359,6 +371,8 @@ pub fn check_incompatible_options_for_ci_rustc(
frame_pointers: _,
break_on_ice: _,
parallel_frontend_threads: _,
bootstrap_override_lld: _,
bootstrap_override_lld_legacy: _,
} = ci_rust_config;

// There are two kinds of checks for CI rustc incompatible options:
Expand All @@ -374,7 +388,6 @@ pub fn check_incompatible_options_for_ci_rustc(
err!(current_rust_config.debuginfo_level_rustc, debuginfo_level_rustc, "rust");
err!(current_rust_config.rpath, rpath, "rust");
err!(current_rust_config.strip, strip, "rust");
err!(current_rust_config.lld_mode, lld_mode, "rust");
err!(current_rust_config.llvm_tools, llvm_tools, "rust");
err!(current_rust_config.llvm_bitcode_linker, llvm_bitcode_linker, "rust");
err!(current_rust_config.jemalloc, jemalloc, "rust");
Expand Down
12 changes: 6 additions & 6 deletions src/bootstrap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use utils::exec::ExecutionContext;

use crate::core::builder;
use crate::core::builder::Kind;
use crate::core::config::{DryRun, LldMode, LlvmLibunwind, TargetSelection, flags};
use crate::core::config::{BootstrapOverrideLld, DryRun, LlvmLibunwind, TargetSelection, flags};
use crate::utils::exec::{BootstrapCommand, command};
use crate::utils::helpers::{self, dir_is_empty, exe, libdir, set_file_times, split_debuginfo};

Expand Down Expand Up @@ -1358,14 +1358,14 @@ impl Build {
&& !target.is_msvc()
{
Some(self.cc(target))
} else if self.config.lld_mode.is_used()
} else if self.config.bootstrap_override_lld.is_used()
&& self.is_lld_direct_linker(target)
&& self.host_target == target
{
match self.config.lld_mode {
LldMode::SelfContained => Some(self.initial_lld.clone()),
LldMode::External => Some("lld".into()),
LldMode::Unused => None,
match self.config.bootstrap_override_lld {
BootstrapOverrideLld::SelfContained => Some(self.initial_lld.clone()),
BootstrapOverrideLld::External => Some("lld".into()),
BootstrapOverrideLld::None => None,
}
} else {
None
Expand Down
5 changes: 5 additions & 0 deletions src/bootstrap/src/utils/change_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -556,4 +556,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
severity: ChangeSeverity::Info,
summary: "New option `build.windows-rc` that will override which resource compiler on Windows will be used to compile Rust.",
},
ChangeInfo {
change_id: 99999,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you accidentally forgot to update this. 😅

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦 I'll update it the next time we modify the change tracker, to avoid churn. Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case I might as well fix it in #146929, assuming another opportunity doesn’t come up first.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, let's do that please 😇 Thanks!

severity: ChangeSeverity::Warning,
summary: "The `rust.use-lld` option has been renamed to `rust.bootstrap-override-lld`. Note that it only serves for overriding the linker used when building Rust code in bootstrap to be LLD.",
},
];
Loading
Loading