Skip to content

Commit 1531ca2

Browse files
authored
Rollup merge of rust-lang#129257 - ChrisDenton:rename-null-descriptor, r=jieyouxu
Allow rust staticlib to work with MSVC's /WHOLEARCHIVE This fixes rust-lang#129020 by renaming the `__NULL_IMPORT_DESCRIPTOR` to prevent conflicts. try-job: dist-i686-msvc
2 parents d3d65dc + 40af214 commit 1531ca2

File tree

7 files changed

+74
-4
lines changed

7 files changed

+74
-4
lines changed

Cargo.lock

+2-2
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,9 @@ dependencies = [
195195

196196
[[package]]
197197
name = "ar_archive_writer"
198-
version = "0.4.0"
198+
version = "0.4.2"
199199
source = "registry+https://github.com/rust-lang/crates.io-index"
200-
checksum = "de11a9d32db3327f981143bdf699ade4d637c6887b13b97e6e91a9154666963c"
200+
checksum = "01667f6f40216b9a0b2945e05fed5f1ad0ab6470e69cb9378001e37b1c0668e4"
201201
dependencies = [
202202
"object 0.36.3",
203203
]

compiler/rustc_codegen_ssa/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ edition = "2021"
55

66
[dependencies]
77
# tidy-alphabetical-start
8-
ar_archive_writer = "0.4.0"
8+
ar_archive_writer = "0.4.2"
99
arrayvec = { version = "0.7", default-features = false }
1010
bitflags = "2.4.1"
1111
cc = "1.0.90"

compiler/rustc_codegen_ssa/src/back/archive.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,11 @@ pub trait ArchiveBuilderBuilder {
108108
&exports,
109109
machine,
110110
!sess.target.is_like_msvc,
111-
/*comdat=*/ false,
111+
// Enable compatibility with MSVC's `/WHOLEARCHIVE` flag.
112+
// Without this flag a duplicate symbol error would be emitted
113+
// when linking a rust staticlib using `/WHOLEARCHIVE`.
114+
// See #129020
115+
true,
112116
) {
113117
sess.dcx()
114118
.emit_fatal(ErrorCreatingImportLibrary { lib_name, error: error.to_string() });

tests/run-make/msvc-wholearchive/c.c

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// This page is intentionally left blank
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
LIBRARY dll
2+
EXPORTS
3+
hello
4+
number
+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//! This is a regression test for #129020
2+
//! It ensures we can use `/WHOLEARCHIVE` to link a rust staticlib into DLL
3+
//! using the MSVC linker
4+
5+
//@ only-msvc
6+
// Reason: this is testing the MSVC linker
7+
8+
use std::path::PathBuf;
9+
10+
use run_make_support::{cc, cmd, env_var, extra_c_flags, rustc};
11+
12+
fn main() {
13+
// Build the staticlib
14+
rustc().crate_type("staticlib").input("static.rs").output("static.lib").run();
15+
// Build an empty object to pass to the linker.
16+
cc().input("c.c").output("c.obj").args(["-c"]).run();
17+
18+
// Find the C toolchain's linker.
19+
let mut linker = PathBuf::from(env_var("CC"));
20+
let linker_flavour = if linker.file_stem().is_some_and(|s| s == "cl") {
21+
linker.set_file_name("link.exe");
22+
"msvc"
23+
} else if linker.file_stem().is_some_and(|s| s == "clang-cl") {
24+
linker.set_file_name("lld-link.exe");
25+
"llvm"
26+
} else {
27+
panic!("unknown C toolchain");
28+
};
29+
30+
// As a sanity check, make sure this works without /WHOLEARCHIVE.
31+
// Otherwise the actual test failure may be caused by something else.
32+
cmd(&linker)
33+
.args(["c.obj", "./static.lib", "-dll", "-def:dll.def", "-out:dll.dll"])
34+
.args(extra_c_flags())
35+
.run();
36+
37+
// FIXME(@ChrisDenton): this doesn't currently work with llvm's lld-link for other reasons.
38+
// May need LLVM patches.
39+
if linker_flavour == "msvc" {
40+
// Link in the staticlib using `/WHOLEARCHIVE` and produce a DLL.
41+
cmd(&linker)
42+
.args([
43+
"c.obj",
44+
"-WHOLEARCHIVE:./static.lib",
45+
"-dll",
46+
"-def:dll.def",
47+
"-out:dll_whole_archive.dll",
48+
])
49+
.args(extra_c_flags())
50+
.run();
51+
}
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#[no_mangle]
2+
pub extern "C" fn hello() {
3+
println!("Hello world!");
4+
}
5+
6+
#[no_mangle]
7+
pub extern "C" fn number() -> u32 {
8+
42
9+
}

0 commit comments

Comments
 (0)