From bfba6ef328bbba327cae8918e795c11b89217672 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 28 Jan 2020 19:21:22 +0100 Subject: [PATCH 1/5] Add an option to use LLD to link the compiler on Windows platforms --- config.toml.example | 5 +++++ src/bootstrap/bin/rustc.rs | 5 +++++ src/bootstrap/builder.rs | 26 +++++++++++++++++++++++--- src/bootstrap/config.rs | 3 +++ src/bootstrap/lib.rs | 20 ++++++++++++++++++-- src/bootstrap/test.rs | 4 ++-- 6 files changed, 56 insertions(+), 7 deletions(-) diff --git a/config.toml.example b/config.toml.example index c9e17337ee23f..c8aff4af8ffe3 100644 --- a/config.toml.example +++ b/config.toml.example @@ -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. +#use-lld = false + # Indicates whether some LLVM tools, like llvm-objdump, will be made available in the # sysroot. #llvm-tools = false diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index a34ec44566bc1..46e3e4ef6d1f3 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -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"); diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index d9c894aa9c6b1..008af975c33fb 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -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 @@ -949,10 +949,30 @@ impl<'a> Builder<'a> { } } - if let Some(host_linker) = self.linker(compiler.host) { + // FIXME: Don't use LLD if we're compiling libstd, since it fails to link it. + 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| { + 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); } diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 110c8b844d54c..8a01bee220835 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -83,6 +83,7 @@ pub struct Config { pub llvm_use_linker: Option, pub llvm_allow_old_toolchain: Option, + pub use_lld: bool, pub lld_enabled: bool, pub lldb_enabled: bool, pub llvm_tools_enabled: bool, @@ -322,6 +323,7 @@ struct Rust { save_toolstates: Option, codegen_backends: Option>, lld: Option, + use_lld: Option, llvm_tools: Option, lldb: Option, deny_warnings: Option, @@ -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); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 1fee3fd9ac1d2..9755222410357 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -239,9 +239,10 @@ pub struct Build { hosts: Vec>, targets: Vec>, - // 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 @@ -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"); + 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(), @@ -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) -> Option<&Path> { + fn linker(&self, target: Interned, 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) @@ -819,6 +829,12 @@ impl Build { && !target.contains("msvc") { Some(self.cc(target)) + } else if can_use_lld + && self.config.use_lld + && target.contains("pc-windows-msvc") + && self.build == target + { + Some(&self.initial_lld) } else { None } diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 6adf9ddaf3438..189f9e6ccab42 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -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); @@ -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) { cmd.arg("--linker").arg(linker); } From 95318f8d859dc55cc5e06722c96f6e492529d6ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 29 Jan 2020 18:03:13 +0100 Subject: [PATCH 2/5] Link a linking issue --- src/bootstrap/builder.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 008af975c33fb..56d8944e0dd0b 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -949,7 +949,8 @@ impl<'a> Builder<'a> { } } - // FIXME: Don't use LLD if we're compiling libstd, since it fails to link it. + // 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` From 2124a85260fdf0851bb4de369d311bcfc05b205f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 29 Jan 2020 18:05:26 +0100 Subject: [PATCH 3/5] Don't use a whitelist for use_lld --- src/bootstrap/lib.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 9755222410357..5e4bedbeb28f2 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -829,11 +829,7 @@ impl Build { && !target.contains("msvc") { Some(self.cc(target)) - } else if can_use_lld - && self.config.use_lld - && target.contains("pc-windows-msvc") - && self.build == target - { + } else if can_use_lld && self.config.use_lld && self.build == target { Some(&self.initial_lld) } else { None From e763ddc6b9025482edd06ab563f8a3783381aae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sun, 9 Feb 2020 14:26:13 +0100 Subject: [PATCH 4/5] Add some comments --- config.toml.example | 2 ++ src/bootstrap/test.rs | 1 + 2 files changed, 3 insertions(+) diff --git a/config.toml.example b/config.toml.example index c8aff4af8ffe3..632b09b92bd7c 100644 --- a/config.toml.example +++ b/config.toml.example @@ -398,6 +398,8 @@ # 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. +# +# LLD will not be used if we're cross linking or running tests. #use-lld = false # Indicates whether some LLVM tools, like llvm-objdump, will be made available in the diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 189f9e6ccab42..24b679d07cc9d 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1035,6 +1035,7 @@ impl Step for Compiletest { flags.push("-Zunstable-options".to_string()); flags.push(builder.config.cmd.rustc_args().join(" ")); + // Don't use LLD here since we want to test that rustc finds and uses a linker by itself. if let Some(linker) = builder.linker(target, false) { cmd.arg("--linker").arg(linker); } From d304cd0c5543c701bbfec0bd7b0c8b7c142b3bca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sun, 9 Feb 2020 14:35:50 +0100 Subject: [PATCH 5/5] More comments --- config.toml.example | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config.toml.example b/config.toml.example index 632b09b92bd7c..c37cd4a985727 100644 --- a/config.toml.example +++ b/config.toml.example @@ -400,6 +400,8 @@ # and not the LLD compiled during the bootstrap. # # LLD will not be used if we're cross linking or running tests. +# +# Explicitly setting the linker for a target will override this option. #use-lld = false # Indicates whether some LLVM tools, like llvm-objdump, will be made available in the @@ -470,6 +472,7 @@ # Linker to be used to link 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. #linker = "cc" # Path to the `llvm-config` binary of the installation of a custom LLVM to link