]> git.lizzy.rs Git - rust.git/commitdiff
Add an option to use LLD to link the compiler on Windows platforms
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>
Tue, 28 Jan 2020 18:21:22 +0000 (19:21 +0100)
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>
Wed, 29 Jan 2020 17:05:36 +0000 (18:05 +0100)
config.toml.example
src/bootstrap/bin/rustc.rs
src/bootstrap/builder.rs
src/bootstrap/config.rs
src/bootstrap/lib.rs
src/bootstrap/test.rs

index c9e17337ee23f801857093ec1237bbb833ae17b3..c8aff4af8ffe3114b6604db92ae879e31013f4cd 100644 (file)
 # 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
index a34ec44566bc17e023d9c9c6f718f9beee3d53be..46e3e4ef6d1f371c24de0bc4a9ff9747bd5cca30 100644 (file)
@@ -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");
index d9c894aa9c6b1d6a32023c99201e01528246b3cd..008af975c33fb77eb9cea62226d04d62caaca7fb 100644 (file)
@@ -694,7 +694,7 @@ pub fn rustdoc_cmd(&self, compiler: Compiler) -> Command {
         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 @@ pub fn cargo(
             }
         }
 
-        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<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);
         }
index 110c8b844d54c6d68357b3161e753fda23c7d2a1..8a01bee2208357123d33d0f0ee5d1d58fdb5e7ec 100644 (file)
@@ -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,
@@ -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>,
@@ -566,6 +568,7 @@ pub fn parse(args: &[String]) -> 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);
index 1fee3fd9ac1d26038726a25287061fd75e7ade5e..9755222410357cdd8e4b872b1c792b8ebe2e6627 100644 (file)
@@ -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
@@ -343,9 +344,18 @@ pub fn new(config: Config) -> 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 @@ fn cxx(&self, target: Interned<String>) -> Result<&Path, String> {
     }
 
     /// 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)
@@ -819,6 +829,12 @@ fn linker(&self, target: Interned<String>) -> Option<&Path> {
             && !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
         }
index 6adf9ddaf3438e15b5cab0d6fc3b41e9145b8d6c..189f9e6ccab427ee68757c22831a6c156dccecae 100644 (file)
@@ -596,7 +596,7 @@ fn run(self, builder: &Builder<'_>) {
             .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 @@ fn run(self, builder: &Builder<'_>) {
         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);
         }