From 9a2362a76eac403552fd93a0977e10731f3d9de3 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 26 Feb 2025 16:24:39 +0300 Subject: [PATCH] linker: Fix escaping style for response files on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we use a С/С++ compiler as linker, then Posix-style escaping should be used. --- compiler/rustc_codegen_ssa/src/back/link.rs | 8 ++++++-- src/bootstrap/src/core/build_steps/test.rs | 20 ++++++++++++++++---- src/bootstrap/src/core/builder/cargo.rs | 6 +++--- src/bootstrap/src/core/builder/mod.rs | 2 +- src/bootstrap/src/utils/helpers.rs | 14 +++++++++++--- 5 files changed, 37 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index b090730ac6b51..5054ae561c043 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1726,8 +1726,12 @@ fn exec_linker( args.push_str( &Escape { arg: arg.to_str().unwrap(), - // LLD also uses MSVC-like parsing for @-files by default when running on windows hosts - is_like_msvc: sess.target.is_like_msvc || (cfg!(windows) && flavor.uses_lld()), + // Windows-style escaping for @-files is used by + // - all linkers targeting MSVC-like targets, including LLD + // - all LLD flavors running on Windows hosts + // С/С++ compilers use Posix-style escaping (except clang-cl, which we do not use). + is_like_msvc: sess.target.is_like_msvc + || (cfg!(windows) && flavor.uses_lld() && !flavor.uses_cc()), } .to_string(), ); diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index dfcf26cedd65f..e4f888ac793c0 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -269,7 +269,13 @@ impl Step for Cargotest { .args(builder.config.test_args()) .env("RUSTC", builder.rustc(compiler)) .env("RUSTDOC", builder.rustdoc(compiler)); - add_rustdoc_cargo_linker_args(&mut cmd, builder, compiler.host, LldThreads::No); + add_rustdoc_cargo_linker_args( + &mut cmd, + builder, + compiler.host, + LldThreads::No, + compiler.stage, + ); cmd.delay_failure().run(builder); } } @@ -847,7 +853,7 @@ impl Step for RustdocTheme { .env("CFG_RELEASE_CHANNEL", &builder.config.channel) .env("RUSTDOC_REAL", builder.rustdoc(self.compiler)) .env("RUSTC_BOOTSTRAP", "1"); - cmd.args(linker_args(builder, self.compiler.host, LldThreads::No)); + cmd.args(linker_args(builder, self.compiler.host, LldThreads::No, self.compiler.stage)); cmd.delay_failure().run(builder); } @@ -1023,7 +1029,13 @@ impl Step for RustdocGUI { cmd.env("RUSTDOC", builder.rustdoc(self.compiler)) .env("RUSTC", builder.rustc(self.compiler)); - add_rustdoc_cargo_linker_args(&mut cmd, builder, self.compiler.host, LldThreads::No); + add_rustdoc_cargo_linker_args( + &mut cmd, + builder, + self.compiler.host, + LldThreads::No, + self.compiler.stage, + ); for path in &builder.paths { if let Some(p) = helpers::is_valid_test_suite_arg(path, "tests/rustdoc-gui", builder) { @@ -1883,7 +1895,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the let mut hostflags = flags.clone(); hostflags.push(format!("-Lnative={}", builder.test_helpers_out(compiler.host).display())); - hostflags.extend(linker_flags(builder, compiler.host, LldThreads::No)); + hostflags.extend(linker_flags(builder, compiler.host, LldThreads::No, compiler.stage)); let mut targetflags = flags; targetflags.push(format!("-Lnative={}", builder.test_helpers_out(target).display())); diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 4f6d53e9fc893..8ada7afed8e92 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -260,7 +260,7 @@ impl Cargo { } } - for arg in linker_args(builder, compiler.host, LldThreads::Yes) { + for arg in linker_args(builder, compiler.host, LldThreads::Yes, 0) { self.hostflags.arg(&arg); } @@ -270,10 +270,10 @@ impl Cargo { } // We want to set -Clinker using Cargo, therefore we only call `linker_flags` and not // `linker_args` here. - for flag in linker_flags(builder, target, LldThreads::Yes) { + for flag in linker_flags(builder, target, LldThreads::Yes, compiler.stage) { self.rustflags.arg(&flag); } - for arg in linker_args(builder, target, LldThreads::Yes) { + for arg in linker_args(builder, target, LldThreads::Yes, compiler.stage) { self.rustdocflags.arg(&arg); } diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 9c04f097bee27..c8e2856bdc874 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -1462,7 +1462,7 @@ impl<'a> Builder<'a> { cmd.arg("-Dwarnings"); } cmd.arg("-Znormalize-docs"); - cmd.args(linker_args(self, compiler.host, LldThreads::Yes)); + cmd.args(linker_args(self, compiler.host, LldThreads::Yes, compiler.stage)); cmd } diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 3fee397da091d..7ad308cd06728 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -430,8 +430,9 @@ pub fn linker_args( builder: &Builder<'_>, target: TargetSelection, lld_threads: LldThreads, + stage: u32, ) -> Vec { - let mut args = linker_flags(builder, target, lld_threads); + let mut args = linker_flags(builder, target, lld_threads, stage); if let Some(linker) = builder.linker(target) { args.push(format!("-Clinker={}", linker.display())); @@ -446,12 +447,18 @@ pub fn linker_flags( builder: &Builder<'_>, target: TargetSelection, lld_threads: LldThreads, + stage: u32, ) -> Vec { let mut args = vec![]; if !builder.is_lld_direct_linker(target) && builder.config.lld_mode.is_used() { match builder.config.lld_mode { LldMode::External => { - args.push("-Clinker-flavor=gnu-lld-cc".to_string()); + // cfg(bootstrap) - remove after updating bootstrap compiler (#137498) + if stage == 0 && target.is_windows() { + args.push("-Clink-arg=-fuse-ld=lld".to_string()); + } else { + args.push("-Clinker-flavor=gnu-lld-cc".to_string()); + } // FIXME(kobzol): remove this flag once MCP510 gets stabilized args.push("-Zunstable-options".to_string()); } @@ -479,8 +486,9 @@ pub fn add_rustdoc_cargo_linker_args( builder: &Builder<'_>, target: TargetSelection, lld_threads: LldThreads, + stage: u32, ) { - let args = linker_args(builder, target, lld_threads); + let args = linker_args(builder, target, lld_threads, stage); let mut flags = cmd .get_envs() .find_map(|(k, v)| if k == OsStr::new("RUSTDOCFLAGS") { v } else { None })