Skip to content

Commit 7ee6dab

Browse files
committed
Revert "Sema: Stop adding Windows implib link inputs for extern "..." syntax."
This reverts commit b461d07. After some discussion in the team, we've decided that this is too disruptive, especially because the linker errors are less than helpful. That's a fixable problem, so we might reconsider this in the future, but revert it for now.
1 parent 9a158c1 commit 7ee6dab

File tree

10 files changed

+46
-78
lines changed

10 files changed

+46
-78
lines changed

build.zig

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,6 @@ pub fn build(b: *std.Build) !void {
452452
.desc = "Run the behavior tests",
453453
.optimize_modes = optimization_modes,
454454
.include_paths = &.{},
455-
.windows_libs = &.{},
456455
.skip_single_threaded = skip_single_threaded,
457456
.skip_non_native = skip_non_native,
458457
.skip_freebsd = skip_freebsd,
@@ -475,7 +474,6 @@ pub fn build(b: *std.Build) !void {
475474
.desc = "Run the @cImport tests",
476475
.optimize_modes = optimization_modes,
477476
.include_paths = &.{"test/c_import"},
478-
.windows_libs = &.{},
479477
.skip_single_threaded = true,
480478
.skip_non_native = skip_non_native,
481479
.skip_freebsd = skip_freebsd,
@@ -496,7 +494,6 @@ pub fn build(b: *std.Build) !void {
496494
.desc = "Run the compiler_rt tests",
497495
.optimize_modes = optimization_modes,
498496
.include_paths = &.{},
499-
.windows_libs = &.{},
500497
.skip_single_threaded = true,
501498
.skip_non_native = skip_non_native,
502499
.skip_freebsd = skip_freebsd,
@@ -518,7 +515,6 @@ pub fn build(b: *std.Build) !void {
518515
.desc = "Run the zigc tests",
519516
.optimize_modes = optimization_modes,
520517
.include_paths = &.{},
521-
.windows_libs = &.{},
522518
.skip_single_threaded = true,
523519
.skip_non_native = skip_non_native,
524520
.skip_freebsd = skip_freebsd,
@@ -540,12 +536,6 @@ pub fn build(b: *std.Build) !void {
540536
.desc = "Run the standard library tests",
541537
.optimize_modes = optimization_modes,
542538
.include_paths = &.{},
543-
.windows_libs = &.{
544-
"advapi32",
545-
"crypt32",
546-
"iphlpapi",
547-
"ws2_32",
548-
},
549539
.skip_single_threaded = skip_single_threaded,
550540
.skip_non_native = skip_non_native,
551541
.skip_freebsd = skip_freebsd,
@@ -743,12 +733,6 @@ fn addCompilerMod(b: *std.Build, options: AddCompilerModOptions) *std.Build.Modu
743733
compiler_mod.addImport("aro", aro_mod);
744734
compiler_mod.addImport("aro_translate_c", aro_translate_c_mod);
745735

746-
if (options.target.result.os.tag == .windows) {
747-
compiler_mod.linkSystemLibrary("advapi32", .{});
748-
compiler_mod.linkSystemLibrary("crypt32", .{});
749-
compiler_mod.linkSystemLibrary("ws2_32", .{});
750-
}
751-
752736
return compiler_mod;
753737
}
754738

@@ -1446,10 +1430,6 @@ fn generateLangRef(b: *std.Build) std.Build.LazyPath {
14461430
}),
14471431
});
14481432

1449-
if (b.graph.host.result.os.tag == .windows) {
1450-
doctest_exe.root_module.linkSystemLibrary("advapi32", .{});
1451-
}
1452-
14531433
var dir = b.build_root.handle.openDir("doc/langref", .{ .iterate = true }) catch |err| {
14541434
std.debug.panic("unable to open '{f}doc/langref' directory: {s}", .{
14551435
b.build_root, @errorName(err),

src/Compilation.zig

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2185,8 +2185,12 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
21852185
.emit_docs = try options.emit_docs.resolve(arena, &options, .docs),
21862186
};
21872187

2188-
comp.windows_libs = try std.StringArrayHashMapUnmanaged(void).init(gpa, options.windows_lib_names, &.{});
2189-
errdefer comp.windows_libs.deinit(gpa);
2188+
errdefer {
2189+
for (comp.windows_libs.keys()) |windows_lib| gpa.free(windows_lib);
2190+
comp.windows_libs.deinit(gpa);
2191+
}
2192+
try comp.windows_libs.ensureUnusedCapacity(gpa, options.windows_lib_names.len);
2193+
for (options.windows_lib_names) |windows_lib| comp.windows_libs.putAssumeCapacity(try gpa.dupe(u8, windows_lib), {});
21902194

21912195
// Prevent some footguns by making the "any" fields of config reflect
21922196
// the default Module settings.
@@ -2417,13 +2421,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
24172421

24182422
if (comp.emit_bin != null and target.ofmt != .c) {
24192423
if (!comp.skip_linker_dependencies) {
2420-
// These DLLs are always loaded into every Windows process.
2421-
if (target.os.tag == .windows and is_exe_or_dyn_lib) {
2422-
try comp.windows_libs.ensureUnusedCapacity(gpa, 2);
2423-
comp.windows_libs.putAssumeCapacity("kernel32", {});
2424-
comp.windows_libs.putAssumeCapacity("ntdll", {});
2425-
}
2426-
24272424
// If we need to build libc for the target, add work items for it.
24282425
// We go through the work queue so that building can be done in parallel.
24292426
// If linking against host libc installation, instead queue up jobs
@@ -2512,7 +2509,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
25122509

25132510
// When linking mingw-w64 there are some import libs we always need.
25142511
try comp.windows_libs.ensureUnusedCapacity(gpa, mingw.always_link_libs.len);
2515-
for (mingw.always_link_libs) |name| comp.windows_libs.putAssumeCapacity(name, {});
2512+
for (mingw.always_link_libs) |name| comp.windows_libs.putAssumeCapacity(try gpa.dupe(u8, name), {});
25162513
} else {
25172514
return error.LibCUnavailable;
25182515
}
@@ -2610,6 +2607,7 @@ pub fn destroy(comp: *Compilation) void {
26102607
comp.c_object_work_queue.deinit();
26112608
comp.win32_resource_work_queue.deinit();
26122609

2610+
for (comp.windows_libs.keys()) |windows_lib| gpa.free(windows_lib);
26132611
comp.windows_libs.deinit(gpa);
26142612

26152613
{
@@ -7795,6 +7793,27 @@ fn getCrtPathsInner(
77957793
};
77967794
}
77977795

7796+
pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void {
7797+
// Avoid deadlocking on building import libs such as kernel32.lib
7798+
// This can happen when the user uses `build-exe foo.obj -lkernel32` and
7799+
// then when we create a sub-Compilation for zig libc, it also tries to
7800+
// build kernel32.lib.
7801+
if (comp.skip_linker_dependencies) return;
7802+
const target = &comp.root_mod.resolved_target.result;
7803+
if (target.os.tag != .windows or target.ofmt == .c) return;
7804+
7805+
// This happens when an `extern "foo"` function is referenced.
7806+
// If we haven't seen this library yet and we're targeting Windows, we need
7807+
// to queue up a work item to produce the DLL import library for this.
7808+
const gop = try comp.windows_libs.getOrPut(comp.gpa, lib_name);
7809+
if (gop.found_existing) return;
7810+
{
7811+
errdefer _ = comp.windows_libs.pop();
7812+
gop.key_ptr.* = try comp.gpa.dupe(u8, lib_name);
7813+
}
7814+
try comp.queueJob(.{ .windows_import_lib = gop.index });
7815+
}
7816+
77987817
/// This decides the optimization mode for all zig-provided libraries, including
77997818
/// compiler-rt, libcxx, libc, libunwind, etc.
78007819
pub fn compilerRtOptMode(comp: Compilation) std.builtin.OptimizeMode {

src/Sema.zig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8906,6 +8906,14 @@ fn resolveGenericBody(
89068906
return sema.resolveConstDefinedValue(block, src, result, reason);
89078907
}
89088908

8909+
/// Given a library name, examines if the library name should end up in
8910+
/// `link.File.Options.windows_libs` table (for example, libc is always
8911+
/// specified via dedicated flag `link_libc` instead),
8912+
/// and puts it there if it doesn't exist.
8913+
/// It also dupes the library name which can then be saved as part of the
8914+
/// respective `Decl` (either `ExternFn` or `Var`).
8915+
/// The liveness of the duped library name is tied to liveness of `Zcu`.
8916+
/// To deallocate, call `deinit` on the respective `Decl` (`ExternFn` or `Var`).
89098917
pub fn handleExternLibName(
89108918
sema: *Sema,
89118919
block: *Block,
@@ -8955,6 +8963,11 @@ pub fn handleExternLibName(
89558963
.{ lib_name, lib_name },
89568964
);
89578965
}
8966+
comp.addLinkLib(lib_name) catch |err| {
8967+
return sema.fail(block, src_loc, "unable to add link lib '{s}': {s}", .{
8968+
lib_name, @errorName(err),
8969+
});
8970+
};
89588971
}
89598972
}
89608973

src/libs/mingw.zig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,6 @@ const mingw32_winpthreads_src = [_][]const u8{
10121012
"winpthreads" ++ path.sep_str ++ "thread.c",
10131013
};
10141014

1015-
// Note: kernel32 and ntdll are always linked even without targeting MinGW-w64.
10161015
pub const always_link_libs = [_][]const u8{
10171016
"api-ms-win-crt-conio-l1-1-0",
10181017
"api-ms-win-crt-convert-l1-1-0",
@@ -1030,6 +1029,8 @@ pub const always_link_libs = [_][]const u8{
10301029
"api-ms-win-crt-time-l1-1-0",
10311030
"api-ms-win-crt-utility-l1-1-0",
10321031
"advapi32",
1032+
"kernel32",
1033+
"ntdll",
10331034
"shell32",
10341035
"user32",
10351036
};

src/main.zig

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,6 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
312312
return jitCmd(gpa, arena, cmd_args, .{
313313
.cmd_name = "resinator",
314314
.root_src_path = "resinator/main.zig",
315-
.windows_libs = &.{"advapi32"},
316315
.depend_on_aro = true,
317316
.prepend_zig_lib_dir_path = true,
318317
.server = use_server,
@@ -337,7 +336,6 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
337336
return jitCmd(gpa, arena, cmd_args, .{
338337
.cmd_name = "std",
339338
.root_src_path = "std-docs.zig",
340-
.windows_libs = &.{"ws2_32"},
341339
.prepend_zig_lib_dir_path = true,
342340
.prepend_zig_exe_path = true,
343341
.prepend_global_cache_path = true,
@@ -3659,6 +3657,7 @@ fn buildOutputType(
36593657
} else if (target.os.tag == .windows) {
36603658
try test_exec_args.appendSlice(arena, &.{
36613659
"--subsystem", "console",
3660+
"-lkernel32", "-lntdll",
36623661
});
36633662
}
36643663

@@ -3862,8 +3861,7 @@ fn createModule(
38623861
.only_compiler_rt => continue,
38633862
}
38643863

3865-
// We currently prefer import libraries provided by MinGW-w64 even for MSVC.
3866-
if (target.os.tag == .windows) {
3864+
if (target.isMinGW()) {
38673865
const exists = mingw.libExists(arena, target, create_module.dirs.zig_lib, lib_name) catch |err| {
38683866
fatal("failed to check zig installation for DLL import libs: {s}", .{
38693867
@errorName(err),
@@ -5375,14 +5373,6 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
53755373

53765374
try root_mod.deps.put(arena, "@build", build_mod);
53775375

5378-
var windows_libs: std.StringArrayHashMapUnmanaged(void) = .empty;
5379-
5380-
if (resolved_target.result.os.tag == .windows) {
5381-
try windows_libs.ensureUnusedCapacity(arena, 2);
5382-
windows_libs.putAssumeCapacity("advapi32", {});
5383-
windows_libs.putAssumeCapacity("ws2_32", {}); // for `--listen` (web interface)
5384-
}
5385-
53865376
const comp = Compilation.create(gpa, arena, .{
53875377
.libc_installation = libc_installation,
53885378
.dirs = dirs,
@@ -5405,7 +5395,6 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
54055395
.cache_mode = .whole,
54065396
.reference_trace = reference_trace,
54075397
.debug_compile_errors = debug_compile_errors,
5408-
.windows_lib_names = windows_libs.keys(),
54095398
}) catch |err| {
54105399
fatal("unable to create compilation: {s}", .{@errorName(err)});
54115400
};
@@ -5509,7 +5498,6 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
55095498
const JitCmdOptions = struct {
55105499
cmd_name: []const u8,
55115500
root_src_path: []const u8,
5512-
windows_libs: []const []const u8 = &.{},
55135501
prepend_zig_lib_dir_path: bool = false,
55145502
prepend_global_cache_path: bool = false,
55155503
prepend_zig_exe_path: bool = false,
@@ -5626,13 +5614,6 @@ fn jitCmd(
56265614
try root_mod.deps.put(arena, "aro", aro_mod);
56275615
}
56285616

5629-
var windows_libs: std.StringArrayHashMapUnmanaged(void) = .empty;
5630-
5631-
if (resolved_target.result.os.tag == .windows) {
5632-
try windows_libs.ensureUnusedCapacity(arena, options.windows_libs.len);
5633-
for (options.windows_libs) |lib| windows_libs.putAssumeCapacity(lib, {});
5634-
}
5635-
56365617
const comp = Compilation.create(gpa, arena, .{
56375618
.dirs = dirs,
56385619
.root_name = options.cmd_name,
@@ -5643,7 +5624,6 @@ fn jitCmd(
56435624
.self_exe_path = self_exe_path,
56445625
.thread_pool = &thread_pool,
56455626
.cache_mode = .whole,
5646-
.windows_lib_names = windows_libs.keys(),
56475627
}) catch |err| {
56485628
fatal("unable to create compilation: {s}", .{@errorName(err)});
56495629
};

test/standalone/simple/build.zig

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,6 @@ pub fn build(b: *std.Build) void {
5050
});
5151
if (case.link_libc) exe.root_module.link_libc = true;
5252

53-
if (resolved_target.result.os.tag == .windows) {
54-
exe.root_module.linkSystemLibrary("advapi32", .{});
55-
}
56-
5753
_ = exe.getEmittedBin();
5854

5955
step.dependOn(&exe.step);
@@ -70,10 +66,6 @@ pub fn build(b: *std.Build) void {
7066
});
7167
if (case.link_libc) exe.root_module.link_libc = true;
7268

73-
if (resolved_target.result.os.tag == .windows) {
74-
exe.root_module.linkSystemLibrary("advapi32", .{});
75-
}
76-
7769
const run = b.addRunArtifact(exe);
7870
step.dependOn(&run.step);
7971
}

test/standalone/windows_argv/build.zig

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ pub fn build(b: *std.Build) !void {
4747
}),
4848
});
4949

50-
fuzz.root_module.linkSystemLibrary("advapi32", .{});
51-
5250
const fuzz_max_iterations = b.option(u64, "iterations", "The max fuzz iterations (default: 100)") orelse 100;
5351
const fuzz_iterations_arg = std.fmt.allocPrint(b.allocator, "{}", .{fuzz_max_iterations}) catch @panic("oom");
5452

test/standalone/windows_bat_args/build.zig

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ pub fn build(b: *std.Build) !void {
2828
}),
2929
});
3030

31-
test_exe.root_module.linkSystemLibrary("advapi32", .{});
32-
3331
const run = b.addRunArtifact(test_exe);
3432
run.addArtifactArg(echo_args);
3533
run.expectExitCode(0);
@@ -46,8 +44,6 @@ pub fn build(b: *std.Build) !void {
4644
}),
4745
});
4846

49-
fuzz.root_module.linkSystemLibrary("advapi32", .{});
50-
5147
const fuzz_max_iterations = b.option(u64, "iterations", "The max fuzz iterations (default: 100)") orelse 100;
5248
const fuzz_iterations_arg = std.fmt.allocPrint(b.allocator, "{}", .{fuzz_max_iterations}) catch @panic("oom");
5349

test/standalone/windows_spawn/build.zig

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ pub fn build(b: *std.Build) void {
2828
}),
2929
});
3030

31-
main.root_module.linkSystemLibrary("advapi32", .{});
32-
3331
const run = b.addRunArtifact(main);
3432
run.addArtifactArg(hello);
3533
run.expectExitCode(0);

test/tests.zig

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2238,7 +2238,6 @@ const ModuleTestOptions = struct {
22382238
desc: []const u8,
22392239
optimize_modes: []const OptimizeMode,
22402240
include_paths: []const []const u8,
2241-
windows_libs: []const []const u8,
22422241
skip_single_threaded: bool,
22432242
skip_non_native: bool,
22442243
skip_freebsd: bool,
@@ -2373,10 +2372,6 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
23732372

23742373
for (options.include_paths) |include_path| these_tests.root_module.addIncludePath(b.path(include_path));
23752374

2376-
if (target.os.tag == .windows) {
2377-
for (options.windows_libs) |lib| these_tests.root_module.linkSystemLibrary(lib, .{});
2378-
}
2379-
23802375
const qualified_name = b.fmt("{s}-{s}-{s}-{s}{s}{s}{s}{s}{s}{s}", .{
23812376
options.name,
23822377
triple_txt,
@@ -2672,10 +2667,6 @@ pub fn addIncrementalTests(b: *std.Build, test_step: *Step) !void {
26722667
}),
26732668
});
26742669

2675-
if (b.graph.host.result.os.tag == .windows) {
2676-
incr_check.root_module.linkSystemLibrary("advapi32", .{});
2677-
}
2678-
26792670
var dir = try b.build_root.handle.openDir("test/incremental", .{ .iterate = true });
26802671
defer dir.close();
26812672

0 commit comments

Comments
 (0)