From 3ad82500ba53c5ad03695e5c57f3a77b3098bfeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Wed, 1 Oct 2025 14:54:21 +0200 Subject: [PATCH] Add `rust-mingw` component for `*-windows-gnullvm` hosts --- .../src/spec/base/windows_gnullvm.rs | 16 ++++--- .../targets/aarch64_pc_windows_gnullvm.rs | 3 +- .../spec/targets/x86_64_pc_windows_gnullvm.rs | 1 + src/bootstrap/src/core/build_steps/compile.rs | 2 +- src/bootstrap/src/core/build_steps/dist.rs | 48 ++++++++++++++++++- .../src/core/config/target_selection.rs | 4 ++ src/tools/build-manifest/src/main.rs | 2 +- 7 files changed, 65 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs index 58aff198a6601..3bd8ebd0ed3d5 100644 --- a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs @@ -1,8 +1,9 @@ use std::borrow::Cow; +use crate::spec::crt_objects::pre_mingw_self_contained; use crate::spec::{ - Abi, BinaryFormat, Cc, DebuginfoKind, Env, LinkerFlavor, Lld, Os, SplitDebuginfo, - TargetOptions, cvs, + Abi, BinaryFormat, Cc, DebuginfoKind, Env, LinkSelfContainedDefault, LinkerFlavor, Lld, Os, + SplitDebuginfo, TargetOptions, add_link_args, cvs, }; pub(crate) fn opts() -> TargetOptions { @@ -15,10 +16,11 @@ pub(crate) fn opts() -> TargetOptions { &["-nolibc", "--unwindlib=none"], ); // Order of `late_link_args*` does not matter with LLD. - let late_link_args = TargetOptions::link_args( - LinkerFlavor::Gnu(Cc::Yes, Lld::No), - &["-lmingw32", "-lmingwex", "-lmsvcrt", "-lkernel32", "-luser32"], - ); + let mingw_libs = &["-lmingw32", "-lmingwex", "-lmsvcrt", "-lkernel32", "-luser32"]; + + let mut late_link_args = + TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), mingw_libs); + add_link_args(&mut late_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), mingw_libs); TargetOptions { os: Os::Windows, @@ -36,6 +38,8 @@ pub(crate) fn opts() -> TargetOptions { binary_format: BinaryFormat::Coff, allows_weak_linkage: false, pre_link_args, + pre_link_objects_self_contained: pre_mingw_self_contained(), + link_self_contained: LinkSelfContainedDefault::InferredForMingw, late_link_args, abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs index 9b7db11e2f29a..b6f82e5ccbf40 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs @@ -1,10 +1,11 @@ -use crate::spec::{Arch, FramePointer, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, FramePointer, LinkerFlavor, Lld, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::windows_gnullvm::opts(); base.max_atomic_width = Some(128); base.features = "+v8a,+neon,+fp-armv8".into(); base.linker = Some("aarch64-w64-mingw32-clang".into()); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &["-m", "arm64pe"]); // Microsoft recommends enabling frame pointers on Arm64 Windows. // From https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#integer-registers diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs index 28c9e6251255c..938f1e49f1ef7 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs @@ -6,6 +6,7 @@ pub(crate) fn target() -> Target { base.features = "+cx16,+sse3,+sahf".into(); base.plt_by_default = false; base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &["-m", "i386pep"]); base.max_atomic_width = Some(128); base.linker = Some("x86_64-w64-mingw32-clang".into()); diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 6857a40ada81b..a6704a5675a12 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -448,7 +448,7 @@ fn copy_self_contained_objects( DependencyType::TargetSelfContained, ); } - } else if target.is_windows_gnu() { + } else if target.is_windows_gnu() || target.is_windows_gnullvm() { for obj in ["crt2.o", "dllcrt2.o"].iter() { let src = compiler_file(builder, &builder.cc(target), target, CLang::C, obj); let dst = libdir_self_contained.join(obj); diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 411d42962644d..8bdabb45f0b6c 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -295,6 +295,44 @@ fn make_win_dist(plat_root: &Path, target: TargetSelection, builder: &Builder<'_ } } +fn make_win_llvm_dist(plat_root: &Path, target: TargetSelection, builder: &Builder<'_>) { + if builder.config.dry_run() { + return; + } + + let (_, lib_path) = get_cc_search_dirs(target, builder); + + // Libraries necessary to link the windows-gnullvm toolchains. + // System libraries will be preferred if they are available (see #67429). + let target_libs = [ + // MinGW libs + "libunwind.a", + "libunwind.dll.a", + "libmingw32.a", + "libmingwex.a", + "libmsvcrt.a", + // Windows import libs, remove them once std transitions to raw-dylib + "libkernel32.a", + "libuser32.a", + "libntdll.a", + "libuserenv.a", + "libws2_32.a", + "libdbghelp.a", + ]; + + //Find mingw artifacts we want to bundle + let target_libs = find_files(&target_libs, &lib_path); + + //Copy platform libs to platform-specific lib directory + let plat_target_lib_self_contained_dir = + plat_root.join("lib/rustlib").join(target).join("lib/self-contained"); + fs::create_dir_all(&plat_target_lib_self_contained_dir) + .expect("creating plat_target_lib_self_contained_dir failed"); + for src in target_libs { + builder.copy_link_to_folder(&src, &plat_target_lib_self_contained_dir); + } +} + fn runtime_dll_dist(rust_root: &Path, target: TargetSelection, builder: &Builder<'_>) { if builder.config.dry_run() { return; @@ -394,14 +432,20 @@ impl Step for Mingw { fn run(self, builder: &Builder<'_>) -> Option { let target = self.target; - if !target.ends_with("pc-windows-gnu") || !builder.config.dist_include_mingw_linker { + if !target.contains("pc-windows-gnu") || !builder.config.dist_include_mingw_linker { return None; } let mut tarball = Tarball::new(builder, "rust-mingw", &target.triple); tarball.set_product_name("Rust MinGW"); - make_win_dist(tarball.image_dir(), target, builder); + if target.ends_with("pc-windows-gnu") { + make_win_dist(tarball.image_dir(), target, builder); + } else if target.ends_with("pc-windows-gnullvm") { + make_win_llvm_dist(tarball.image_dir(), target, builder); + } else { + unreachable!(); + } Some(tarball.generate()) } diff --git a/src/bootstrap/src/core/config/target_selection.rs b/src/bootstrap/src/core/config/target_selection.rs index 40b63a7f9c752..47f6d6f386dfb 100644 --- a/src/bootstrap/src/core/config/target_selection.rs +++ b/src/bootstrap/src/core/config/target_selection.rs @@ -86,6 +86,10 @@ impl TargetSelection { self.ends_with("windows-gnu") } + pub fn is_windows_gnullvm(&self) -> bool { + self.ends_with("windows-gnullvm") + } + pub fn is_cygwin(&self) -> bool { self.is_windows() && // ref. https://cygwin.com/pipermail/cygwin/2022-February/250802.html diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 9bae8b241a941..4ffd17ae52189 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -476,7 +476,7 @@ impl Builder { } // so is rust-mingw if it's available for the target PkgType::RustMingw => { - if host.ends_with("pc-windows-gnu") { + if host.contains("pc-windows-gnu") { components.push(host_component(pkg)); } }