From 486864f23593d7aedddf1831f748660311f9ff3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 10 Aug 2024 08:11:22 +0200 Subject: [PATCH] Don't statically link `std` into `rustc_driver` for `windows-gnu` --- src/bootstrap/src/bin/rustc.rs | 8 +++++--- src/bootstrap/src/core/build_steps/compile.rs | 12 +++++++++++- src/bootstrap/src/core/builder.rs | 14 ++++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs index f3198338dc3..d04e2fbeb78 100644 --- a/src/bootstrap/src/bin/rustc.rs +++ b/src/bootstrap/src/bin/rustc.rs @@ -92,9 +92,11 @@ fn main() { // Get the name of the crate we're compiling, if any. let crate_name = parse_value_from_args(&orig_args, "--crate-name"); - // We want everything statically linked into `rustc_driver`, so remove `-C prefer-dynamic` - if crate_name == Some("rustc_driver") && stage != "0" { - // Remove `-C prefer-dynamic` to link `std` statically into `rustc_driver` + // When statically linking `std` into `rustc_driver`, remove `-C prefer-dynamic` + if env::var("RUSTC_LINK_STD_INTO_RUSTC_DRIVER").unwrap() == "1" + && crate_name == Some("rustc_driver") + && stage != "0" + { if let Some(pos) = args.iter().enumerate().position(|(i, a)| { a == "-C" && args.get(i + 1).map(|a| a == "prefer-dynamic").unwrap_or(false) }) { diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 76006bfe0e5..2e521ff7544 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1830,15 +1830,25 @@ impl Step for Assemble { }) .collect::>(); + let link_std_into_rustc_driver = builder.link_std_into_rustc_driver(target_compiler.host); let sysroot = builder.sysroot(target_compiler); let rustc_libdir = builder.rustc_libdir(target_compiler); t!(fs::create_dir_all(&rustc_libdir)); let src_libdir = builder.sysroot_libdir(build_compiler, host); for f in builder.read_dir(&src_libdir) { let filename = f.file_name().into_string().unwrap(); + + // For the later stages which gets distributed only copy over the + // `rustc_driver` library so we don't end up with an extra copy of `std`. + // If we're not statically linking `std` into `rustc_driver`, just copy every library + // to ensure `std` is included. + // We still need `std` for the initial stage as the bootstrap compiler may not + // have the new `rustc_private` linking behavior. let can_be_rustc_dep = filename.starts_with("rustc_driver-") || filename.starts_with("librustc_driver-") - || build_compiler.stage == 0; + || build_compiler.stage == 0 + || !link_std_into_rustc_driver; + if can_be_rustc_dep && (is_dylib(&filename) || is_debug_info(&filename)) && !proc_macros.contains(&filename) diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 41837c0eb89..ccdeb442af4 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -1106,6 +1106,12 @@ impl<'a> Builder<'a> { StepDescription::run(v, self, paths); } + /// Returns if `std` should be statically linked into `rustc_driver`. + /// It's currently not done on `windows-gnu` due to linker bugs. + pub fn link_std_into_rustc_driver(&self, target: TargetSelection) -> bool { + !target.triple.ends_with("-windows-gnu") + } + /// Obtain a compiler at a given stage and for a given host (i.e., this is the target that the /// compiler will run on, *not* the target it will build code for). Explicitly does not take /// `Compiler` since all `Compiler` instances are meant to be obtained through this function, @@ -2165,6 +2171,14 @@ impl<'a> Builder<'a> { if matches!(mode, Mode::Std) { rustflags.arg("-Cprefer-dynamic"); } + if matches!(mode, Mode::Rustc) && !self.link_std_into_rustc_driver(target) { + rustflags.arg("-Cprefer-dynamic"); + } + + cargo.env( + "RUSTC_LINK_STD_INTO_RUSTC_DRIVER", + if self.link_std_into_rustc_driver(target) { "1" } else { "0" }, + ); // When building incrementally we default to a lower ThinLTO import limit // (unless explicitly specified otherwise). This will produce a somewhat