Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an option to use LLD to link the compiler on Windows platforms #68623

Merged
merged 5 commits into from
Feb 9, 2020
Merged
Show file tree
Hide file tree
Changes from 3 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
5 changes: 5 additions & 0 deletions config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,11 @@
# rustc to execute.
#lld = false

# Indicates whether LLD will be used to link Rust crates during bootstrap on
# supported platforms. The LLD from the bootstrap distribution will be used
# and not the LLD compiled during the bootstrap.
Mark-Simulacrum marked this conversation as resolved.
Show resolved Hide resolved
#use-lld = false

# Indicates whether some LLVM tools, like llvm-objdump, will be made available in the
# sysroot.
#llvm-tools = false
Expand Down
5 changes: 5 additions & 0 deletions src/bootstrap/bin/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ fn main() {
cmd.arg(format!("-Clinker={}", host_linker));
}

// Override linker flavor if necessary.
if let Ok(host_linker_flavor) = env::var("RUSTC_HOST_LINKER_FLAVOR") {
cmd.arg(format!("-Clinker-flavor={}", host_linker_flavor));
}

if let Ok(s) = env::var("RUSTC_HOST_CRT_STATIC") {
if s == "true" {
cmd.arg("-C").arg("target-feature=+crt-static");
Expand Down
27 changes: 24 additions & 3 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,7 @@ impl<'a> Builder<'a> {
cmd.env_remove("MAKEFLAGS");
cmd.env_remove("MFLAGS");

if let Some(linker) = self.linker(compiler.host) {
if let Some(linker) = self.linker(compiler.host, true) {
cmd.env("RUSTC_TARGET_LINKER", linker);
}
cmd
Expand Down Expand Up @@ -949,10 +949,31 @@ impl<'a> Builder<'a> {
}
}

if let Some(host_linker) = self.linker(compiler.host) {
// FIXME: Don't use LLD if we're compiling libtest, since it fails to link it.
// See https://github.com/rust-lang/rust/issues/68647.
let can_use_lld = mode != Mode::Std;

// FIXME: The beta compiler doesn't pick the `lld-link` flavor for `*-pc-windows-msvc`
// Remove `RUSTC_HOST_LINKER_FLAVOR` when this is fixed
let lld_linker_flavor = |linker: &Path, target: Interned<String>| {
compiler.stage == 0
&& linker.file_name() == Some(OsStr::new("rust-lld"))
&& target.contains("pc-windows-msvc")
};

if let Some(host_linker) = self.linker(compiler.host, can_use_lld) {
if lld_linker_flavor(host_linker, compiler.host) {
cargo.env("RUSTC_HOST_LINKER_FLAVOR", "lld-link");
}

cargo.env("RUSTC_HOST_LINKER", host_linker);
}
if let Some(target_linker) = self.linker(target) {

if let Some(target_linker) = self.linker(target, can_use_lld) {
if lld_linker_flavor(target_linker, target) {
rustflags.arg("-Clinker-flavor=lld-link");
}

let target = crate::envify(&target);
cargo.env(&format!("CARGO_TARGET_{}_LINKER", target), target_linker);
}
Expand Down
3 changes: 3 additions & 0 deletions src/bootstrap/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ pub struct Config {
pub llvm_use_linker: Option<String>,
pub llvm_allow_old_toolchain: Option<bool>,

pub use_lld: bool,
pub lld_enabled: bool,
pub lldb_enabled: bool,
pub llvm_tools_enabled: bool,
Expand Down Expand Up @@ -322,6 +323,7 @@ struct Rust {
save_toolstates: Option<String>,
codegen_backends: Option<Vec<String>>,
lld: Option<bool>,
use_lld: Option<bool>,
llvm_tools: Option<bool>,
lldb: Option<bool>,
deny_warnings: Option<bool>,
Expand Down Expand Up @@ -566,6 +568,7 @@ impl Config {
if let Some(true) = rust.incremental {
config.incremental = true;
}
set(&mut config.use_lld, rust.use_lld);
set(&mut config.lld_enabled, rust.lld);
set(&mut config.lldb_enabled, rust.lldb);
set(&mut config.llvm_tools_enabled, rust.llvm_tools);
Expand Down
16 changes: 14 additions & 2 deletions src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,10 @@ pub struct Build {
hosts: Vec<Interned<String>>,
targets: Vec<Interned<String>>,

// Stage 0 (downloaded) compiler and cargo or their local rust equivalents
// Stage 0 (downloaded) compiler, lld and cargo or their local rust equivalents
initial_rustc: PathBuf,
initial_cargo: PathBuf,
initial_lld: PathBuf,

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

let initial_sysroot = config.initial_rustc.parent().unwrap().parent().unwrap();
let initial_lld = initial_sysroot
.join("lib")
.join("rustlib")
.join(config.build)
.join("bin")
.join("rust-lld");
Mark-Simulacrum marked this conversation as resolved.
Show resolved Hide resolved

let mut build = Build {
initial_rustc: config.initial_rustc.clone(),
initial_cargo: config.initial_cargo.clone(),
initial_lld,
local_rebuild: config.local_rebuild,
fail_fast: config.cmd.fail_fast(),
doc_tests: config.cmd.doc_tests(),
Expand Down Expand Up @@ -810,7 +820,7 @@ impl Build {
}

/// Returns the path to the linker for the given target if it needs to be overridden.
fn linker(&self, target: Interned<String>) -> Option<&Path> {
fn linker(&self, target: Interned<String>, can_use_lld: bool) -> Option<&Path> {
if let Some(linker) = self.config.target_config.get(&target).and_then(|c| c.linker.as_ref())
{
Some(linker)
Expand All @@ -819,6 +829,8 @@ impl Build {
&& !target.contains("msvc")
{
Some(self.cc(target))
} else if can_use_lld && self.config.use_lld && self.build == target {
Some(&self.initial_lld)
} else {
None
}
Expand Down
4 changes: 2 additions & 2 deletions src/bootstrap/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ impl Step for RustdocTheme {
.env("RUSTDOC_REAL", builder.rustdoc(self.compiler))
.env("RUSTDOC_CRATE_VERSION", builder.rust_version())
.env("RUSTC_BOOTSTRAP", "1");
if let Some(linker) = builder.linker(self.compiler.host) {
if let Some(linker) = builder.linker(self.compiler.host, true) {
cmd.env("RUSTC_TARGET_LINKER", linker);
}
try_run(builder, &mut cmd);
Expand Down Expand Up @@ -1035,7 +1035,7 @@ impl Step for Compiletest {
flags.push("-Zunstable-options".to_string());
flags.push(builder.config.cmd.rustc_args().join(" "));

if let Some(linker) = builder.linker(target) {
if let Some(linker) = builder.linker(target, false) {
Mark-Simulacrum marked this conversation as resolved.
Show resolved Hide resolved
cmd.arg("--linker").arg(linker);
}

Expand Down