Skip to content

Commit bfba6ef

Browse files
committed
Add an option to use LLD to link the compiler on Windows platforms
1 parent eed12bc commit bfba6ef

File tree

6 files changed

+56
-7
lines changed

6 files changed

+56
-7
lines changed

config.toml.example

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,11 @@
395395
# rustc to execute.
396396
#lld = false
397397

398+
# Indicates whether LLD will be used to link Rust crates during bootstrap on
399+
# supported platforms. The LLD from the bootstrap distribution will be used
400+
# and not the LLD compiled during the bootstrap.
401+
#use-lld = false
402+
398403
# Indicates whether some LLVM tools, like llvm-objdump, will be made available in the
399404
# sysroot.
400405
#llvm-tools = false

src/bootstrap/bin/rustc.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ fn main() {
134134
cmd.arg(format!("-Clinker={}", host_linker));
135135
}
136136

137+
// Override linker flavor if necessary.
138+
if let Ok(host_linker_flavor) = env::var("RUSTC_HOST_LINKER_FLAVOR") {
139+
cmd.arg(format!("-Clinker-flavor={}", host_linker_flavor));
140+
}
141+
137142
if let Ok(s) = env::var("RUSTC_HOST_CRT_STATIC") {
138143
if s == "true" {
139144
cmd.arg("-C").arg("target-feature=+crt-static");

src/bootstrap/builder.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,7 @@ impl<'a> Builder<'a> {
694694
cmd.env_remove("MAKEFLAGS");
695695
cmd.env_remove("MFLAGS");
696696

697-
if let Some(linker) = self.linker(compiler.host) {
697+
if let Some(linker) = self.linker(compiler.host, true) {
698698
cmd.env("RUSTC_TARGET_LINKER", linker);
699699
}
700700
cmd
@@ -949,10 +949,30 @@ impl<'a> Builder<'a> {
949949
}
950950
}
951951

952-
if let Some(host_linker) = self.linker(compiler.host) {
952+
// FIXME: Don't use LLD if we're compiling libstd, since it fails to link it.
953+
let can_use_lld = mode != Mode::Std;
954+
955+
// FIXME: The beta compiler doesn't pick the `lld-link` flavor for `*-pc-windows-msvc`
956+
// Remove `RUSTC_HOST_LINKER_FLAVOR` when this is fixed
957+
let lld_linker_flavor = |linker: &Path, target: Interned<String>| {
958+
compiler.stage == 0
959+
&& linker.file_name() == Some(OsStr::new("rust-lld"))
960+
&& target.contains("pc-windows-msvc")
961+
};
962+
963+
if let Some(host_linker) = self.linker(compiler.host, can_use_lld) {
964+
if lld_linker_flavor(host_linker, compiler.host) {
965+
cargo.env("RUSTC_HOST_LINKER_FLAVOR", "lld-link");
966+
}
967+
953968
cargo.env("RUSTC_HOST_LINKER", host_linker);
954969
}
955-
if let Some(target_linker) = self.linker(target) {
970+
971+
if let Some(target_linker) = self.linker(target, can_use_lld) {
972+
if lld_linker_flavor(target_linker, target) {
973+
rustflags.arg("-Clinker-flavor=lld-link");
974+
}
975+
956976
let target = crate::envify(&target);
957977
cargo.env(&format!("CARGO_TARGET_{}_LINKER", target), target_linker);
958978
}

src/bootstrap/config.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ pub struct Config {
8383
pub llvm_use_linker: Option<String>,
8484
pub llvm_allow_old_toolchain: Option<bool>,
8585

86+
pub use_lld: bool,
8687
pub lld_enabled: bool,
8788
pub lldb_enabled: bool,
8889
pub llvm_tools_enabled: bool,
@@ -322,6 +323,7 @@ struct Rust {
322323
save_toolstates: Option<String>,
323324
codegen_backends: Option<Vec<String>>,
324325
lld: Option<bool>,
326+
use_lld: Option<bool>,
325327
llvm_tools: Option<bool>,
326328
lldb: Option<bool>,
327329
deny_warnings: Option<bool>,
@@ -566,6 +568,7 @@ impl Config {
566568
if let Some(true) = rust.incremental {
567569
config.incremental = true;
568570
}
571+
set(&mut config.use_lld, rust.use_lld);
569572
set(&mut config.lld_enabled, rust.lld);
570573
set(&mut config.lldb_enabled, rust.lldb);
571574
set(&mut config.llvm_tools_enabled, rust.llvm_tools);

src/bootstrap/lib.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,10 @@ pub struct Build {
239239
hosts: Vec<Interned<String>>,
240240
targets: Vec<Interned<String>>,
241241

242-
// Stage 0 (downloaded) compiler and cargo or their local rust equivalents
242+
// Stage 0 (downloaded) compiler, lld and cargo or their local rust equivalents
243243
initial_rustc: PathBuf,
244244
initial_cargo: PathBuf,
245+
initial_lld: PathBuf,
245246

246247
// Runtime state filled in later on
247248
// C/C++ compilers and archiver for all targets
@@ -343,9 +344,18 @@ impl Build {
343344
// we always try to use git for LLVM builds
344345
let in_tree_llvm_info = channel::GitInfo::new(false, &src.join("src/llvm-project"));
345346

347+
let initial_sysroot = config.initial_rustc.parent().unwrap().parent().unwrap();
348+
let initial_lld = initial_sysroot
349+
.join("lib")
350+
.join("rustlib")
351+
.join(config.build)
352+
.join("bin")
353+
.join("rust-lld");
354+
346355
let mut build = Build {
347356
initial_rustc: config.initial_rustc.clone(),
348357
initial_cargo: config.initial_cargo.clone(),
358+
initial_lld,
349359
local_rebuild: config.local_rebuild,
350360
fail_fast: config.cmd.fail_fast(),
351361
doc_tests: config.cmd.doc_tests(),
@@ -810,7 +820,7 @@ impl Build {
810820
}
811821

812822
/// Returns the path to the linker for the given target if it needs to be overridden.
813-
fn linker(&self, target: Interned<String>) -> Option<&Path> {
823+
fn linker(&self, target: Interned<String>, can_use_lld: bool) -> Option<&Path> {
814824
if let Some(linker) = self.config.target_config.get(&target).and_then(|c| c.linker.as_ref())
815825
{
816826
Some(linker)
@@ -819,6 +829,12 @@ impl Build {
819829
&& !target.contains("msvc")
820830
{
821831
Some(self.cc(target))
832+
} else if can_use_lld
833+
&& self.config.use_lld
834+
&& target.contains("pc-windows-msvc")
835+
&& self.build == target
836+
{
837+
Some(&self.initial_lld)
822838
} else {
823839
None
824840
}

src/bootstrap/test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ impl Step for RustdocTheme {
596596
.env("RUSTDOC_REAL", builder.rustdoc(self.compiler))
597597
.env("RUSTDOC_CRATE_VERSION", builder.rust_version())
598598
.env("RUSTC_BOOTSTRAP", "1");
599-
if let Some(linker) = builder.linker(self.compiler.host) {
599+
if let Some(linker) = builder.linker(self.compiler.host, true) {
600600
cmd.env("RUSTC_TARGET_LINKER", linker);
601601
}
602602
try_run(builder, &mut cmd);
@@ -1035,7 +1035,7 @@ impl Step for Compiletest {
10351035
flags.push("-Zunstable-options".to_string());
10361036
flags.push(builder.config.cmd.rustc_args().join(" "));
10371037

1038-
if let Some(linker) = builder.linker(target) {
1038+
if let Some(linker) = builder.linker(target, false) {
10391039
cmd.arg("--linker").arg(linker);
10401040
}
10411041

0 commit comments

Comments
 (0)