Skip to content

Commit e9d983f

Browse files
committed
build(windows/gnu): disable gc-sections to work around linker crash
1 parent 0011afb commit e9d983f

File tree

1 file changed

+43
-34
lines changed

1 file changed

+43
-34
lines changed

build.rs

Lines changed: 43 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -28,43 +28,52 @@ fn main() {
2828
let target = env::var("TARGET").unwrap();
2929
println!("cargo:rustc-env=TARGET={target}");
3030

31-
// Set linker options specific to Windows MSVC.
3231
let target_os = env::var("CARGO_CFG_TARGET_OS");
3332
let target_env = env::var("CARGO_CFG_TARGET_ENV");
34-
if !(target_os.as_deref() == Ok("windows") && target_env.as_deref() == Ok("msvc")) {
35-
return;
36-
}
33+
if target_os.as_deref() == Ok("windows") {
34+
match target_env.as_deref() {
35+
Ok("gnu") => {
36+
// Disable `gc-sections` to work around linker crash.
37+
//
38+
// https://stackoverflow.com/a/45107167
39+
// https://github.com/rust-lang/rustup/pull/3849#issuecomment-2142571761
40+
println!("cargo:rustc-link-arg=-Wl,--no-gc-sections");
41+
}
42+
Ok("msvc") => {
43+
// # Only search system32 for DLLs
44+
//
45+
// This applies to DLLs loaded at load time. However, this setting is ignored
46+
// before Windows 10 RS1 (aka 1601).
47+
// https://learn.microsoft.com/en-us/cpp/build/reference/dependentloadflag?view=msvc-170
48+
println!("cargo:cargo:rustc-link-arg-bin=rustup-init=/DEPENDENTLOADFLAG:0x800");
3749

38-
// # Only search system32 for DLLs
39-
//
40-
// This applies to DLLs loaded at load time. However, this setting is ignored
41-
// before Windows 10 RS1 (aka 1601).
42-
// https://learn.microsoft.com/en-us/cpp/build/reference/dependentloadflag?view=msvc-170
43-
println!("cargo:cargo:rustc-link-arg-bin=rustup-init=/DEPENDENTLOADFLAG:0x800");
50+
// # Delay load
51+
//
52+
// Delay load dlls that are not "known DLLs"[1].
53+
// Known DLLs are always loaded from the system directory whereas other DLLs
54+
// are loaded from the application directory. By delay loading the latter
55+
// we can ensure they are instead loaded from the system directory.
56+
// [1]: https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order#factors-that-affect-searching
57+
//
58+
// This will work on all supported Windows versions but it relies on
59+
// us using `SetDefaultDllDirectories` before any libraries are loaded.
60+
// See also: src/bin/rustup-init.rs
61+
let delay_load_dlls = ["bcrypt", "powrprof", "secur32"];
62+
for dll in delay_load_dlls {
63+
println!("cargo:rustc-link-arg-bin=rustup-init=/delayload:{dll}.dll");
64+
}
65+
// When using delayload, it's necessary to also link delayimp.lib
66+
// https://learn.microsoft.com/en-us/cpp/build/reference/dependentloadflag?view=msvc-170
67+
println!("cargo:rustc-link-arg-bin=rustup-init=delayimp.lib");
4468

45-
// # Delay load
46-
//
47-
// Delay load dlls that are not "known DLLs"[1].
48-
// Known DLLs are always loaded from the system directory whereas other DLLs
49-
// are loaded from the application directory. By delay loading the latter
50-
// we can ensure they are instead loaded from the system directory.
51-
// [1]: https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order#factors-that-affect-searching
52-
//
53-
// This will work on all supported Windows versions but it relies on
54-
// us using `SetDefaultDllDirectories` before any libraries are loaded.
55-
// See also: src/bin/rustup-init.rs
56-
let delay_load_dlls = ["bcrypt", "powrprof", "secur32"];
57-
for dll in delay_load_dlls {
58-
println!("cargo:rustc-link-arg-bin=rustup-init=/delayload:{dll}.dll");
69+
// # Turn linker warnings into errors
70+
//
71+
// Rust hides linker warnings meaning mistakes may go unnoticed.
72+
// Turning them into errors forces them to be displayed (and the build to fail).
73+
// If we do want to ignore specific warnings then `/IGNORE:` should be used.
74+
println!("cargo:cargo:rustc-link-arg-bin=rustup-init=/WX");
75+
}
76+
_ => {}
77+
}
5978
}
60-
// When using delayload, it's necessary to also link delayimp.lib
61-
// https://learn.microsoft.com/en-us/cpp/build/reference/dependentloadflag?view=msvc-170
62-
println!("cargo:rustc-link-arg-bin=rustup-init=delayimp.lib");
63-
64-
// # Turn linker warnings into errors
65-
//
66-
// Rust hides linker warnings meaning mistakes may go unnoticed.
67-
// Turning them into errors forces them to be displayed (and the build to fail).
68-
// If we do want to ignore specific warnings then `/IGNORE:` should be used.
69-
println!("cargo:cargo:rustc-link-arg-bin=rustup-init=/WX");
7079
}

0 commit comments

Comments
 (0)