diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs index e69cab956c5..23828f4758d 100644 --- a/src/bootstrap/bin/rustdoc.rs +++ b/src/bootstrap/bin/rustdoc.rs @@ -55,13 +55,9 @@ fn main() { arg.push(&linker); cmd.arg(arg); } - if env::var_os("RUSTDOC_FUSE_LD_LLD").is_some() { + if let Ok(no_threads) = env::var("RUSTDOC_LLD_NO_THREADS") { cmd.arg("-Clink-arg=-fuse-ld=lld"); - if cfg!(windows) { - cmd.arg("-Clink-arg=-Wl,/threads:1"); - } else { - cmd.arg("-Clink-arg=-Wl,--threads=1"); - } + cmd.arg(format!("-Clink-arg=-Wl,{}", no_threads)); } // Cargo doesn't pass RUSTDOCFLAGS to proc_macros: // https://github.com/rust-lang/cargo/issues/4423 diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 7e70e99bb8c..f5def8ba834 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -1152,8 +1152,8 @@ fn lld_flags(&self, target: TargetSelection) -> impl Iterator { options[0] = Some("-Clink-arg=-fuse-ld=lld".to_string()); } - let threads = if target.contains("windows") { "/threads:1" } else { "--threads=1" }; - options[1] = Some(format!("-Clink-arg=-Wl,{}", threads)); + let no_threads = util::lld_flag_no_threads(target.contains("windows")); + options[1] = Some(format!("-Clink-arg=-Wl,{}", no_threads)); } IntoIterator::into_iter(options).flatten() diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 8d491409778..f336f0496a1 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -727,7 +727,10 @@ fn run(self, builder: &Builder<'_>) { cmd.env("RUSTDOC_LINKER", linker); } if builder.is_fuse_ld_lld(self.compiler.host) { - cmd.env("RUSTDOC_FUSE_LD_LLD", "1"); + cmd.env( + "RUSTDOC_LLD_NO_THREADS", + util::lld_flag_no_threads(self.compiler.host.contains("windows")), + ); } try_run(builder, &mut cmd); } diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 0ebabbd5ca5..20c3801f0a5 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -13,6 +13,7 @@ use crate::builder::Builder; use crate::config::{Config, TargetSelection}; +use crate::OnceCell; /// A helper macro to `unwrap` a result except also print out details like: /// @@ -607,3 +608,16 @@ pub fn get_clang_cl_resource_dir(clang_cl_path: &str) -> PathBuf { let clang_rt_dir = clang_rt_builtins.parent().expect("The clang lib folder should exist"); clang_rt_dir.to_path_buf() } + +pub fn lld_flag_no_threads(is_windows: bool) -> &'static str { + static LLD_NO_THREADS: OnceCell<(&'static str, &'static str)> = OnceCell::new(); + let (windows, other) = LLD_NO_THREADS.get_or_init(|| { + let out = output(Command::new("lld").arg("-flavor").arg("ld").arg("--version")); + let newer = match (out.find(char::is_numeric), out.find('.')) { + (Some(b), Some(e)) => out.as_str()[b..e].parse::().ok().unwrap_or(14) > 10, + _ => true, + }; + if newer { ("/threads:1", "--threads=1") } else { ("/no-threads", "--no-threads") } + }); + if is_windows { windows } else { other } +}