Skip to content

Commit 1856883

Browse files
committed
Sema: Stop adding Windows implib link inputs for extern "..." syntax.
Closes #23971.
1 parent 9e340b3 commit 1856883

File tree

10 files changed

+125
-63
lines changed

10 files changed

+125
-63
lines changed

build.zig

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ pub fn build(b: *std.Build) !void {
439439
.desc = "Run the behavior tests",
440440
.optimize_modes = optimization_modes,
441441
.include_paths = &.{},
442+
.windows_libs = &.{},
442443
.skip_single_threaded = skip_single_threaded,
443444
.skip_non_native = skip_non_native,
444445
.skip_freebsd = skip_freebsd,
@@ -461,6 +462,7 @@ pub fn build(b: *std.Build) !void {
461462
.desc = "Run the @cImport tests",
462463
.optimize_modes = optimization_modes,
463464
.include_paths = &.{"test/c_import"},
465+
.windows_libs = &.{},
464466
.skip_single_threaded = true,
465467
.skip_non_native = skip_non_native,
466468
.skip_freebsd = skip_freebsd,
@@ -481,6 +483,7 @@ pub fn build(b: *std.Build) !void {
481483
.desc = "Run the compiler_rt tests",
482484
.optimize_modes = optimization_modes,
483485
.include_paths = &.{},
486+
.windows_libs = &.{},
484487
.skip_single_threaded = true,
485488
.skip_non_native = skip_non_native,
486489
.skip_freebsd = skip_freebsd,
@@ -502,6 +505,7 @@ pub fn build(b: *std.Build) !void {
502505
.desc = "Run the zigc tests",
503506
.optimize_modes = optimization_modes,
504507
.include_paths = &.{},
508+
.windows_libs = &.{},
505509
.skip_single_threaded = true,
506510
.skip_non_native = skip_non_native,
507511
.skip_freebsd = skip_freebsd,
@@ -523,6 +527,12 @@ pub fn build(b: *std.Build) !void {
523527
.desc = "Run the standard library tests",
524528
.optimize_modes = optimization_modes,
525529
.include_paths = &.{},
530+
.windows_libs = &.{
531+
"advapi32",
532+
"crypt32",
533+
"iphlpapi",
534+
"ws2_32",
535+
},
526536
.skip_single_threaded = skip_single_threaded,
527537
.skip_non_native = skip_non_native,
528538
.skip_freebsd = skip_freebsd,
@@ -720,6 +730,12 @@ fn addCompilerMod(b: *std.Build, options: AddCompilerModOptions) *std.Build.Modu
720730
compiler_mod.addImport("aro", aro_mod);
721731
compiler_mod.addImport("aro_translate_c", aro_translate_c_mod);
722732

733+
if (options.target.result.os.tag == .windows) {
734+
compiler_mod.linkSystemLibrary("advapi32", .{});
735+
compiler_mod.linkSystemLibrary("crypt32", .{});
736+
compiler_mod.linkSystemLibrary("ws2_32", .{});
737+
}
738+
723739
return compiler_mod;
724740
}
725741

@@ -1417,6 +1433,10 @@ fn generateLangRef(b: *std.Build) std.Build.LazyPath {
14171433
}),
14181434
});
14191435

1436+
if (b.graph.host.result.os.tag == .windows) {
1437+
doctest_exe.root_module.linkSystemLibrary("advapi32", .{});
1438+
}
1439+
14201440
var dir = b.build_root.handle.openDir("doc/langref", .{ .iterate = true }) catch |err| {
14211441
std.debug.panic("unable to open '{}doc/langref' directory: {s}", .{
14221442
b.build_root, @errorName(err),

src/Compilation.zig

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2306,6 +2306,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
23062306

23072307
if (comp.emit_bin != null and target.ofmt != .c) {
23082308
if (!comp.skip_linker_dependencies) {
2309+
// These DLLs are always loaded into every Windows process.
2310+
if (target.os.tag == .windows and is_exe_or_dyn_lib) {
2311+
try comp.windows_libs.ensureUnusedCapacity(gpa, 2);
2312+
comp.windows_libs.putAssumeCapacity("kernel32", {});
2313+
comp.windows_libs.putAssumeCapacity("ntdll", {});
2314+
}
2315+
23092316
// If we need to build libc for the target, add work items for it.
23102317
// We go through the work queue so that building can be done in parallel.
23112318
// If linking against host libc installation, instead queue up jobs
@@ -7595,27 +7602,6 @@ fn getCrtPathsInner(
75957602
};
75967603
}
75977604

7598-
pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void {
7599-
// Avoid deadlocking on building import libs such as kernel32.lib
7600-
// This can happen when the user uses `build-exe foo.obj -lkernel32` and
7601-
// then when we create a sub-Compilation for zig libc, it also tries to
7602-
// build kernel32.lib.
7603-
if (comp.skip_linker_dependencies) return;
7604-
const target = &comp.root_mod.resolved_target.result;
7605-
if (target.os.tag != .windows or target.ofmt == .c) return;
7606-
7607-
// This happens when an `extern "foo"` function is referenced.
7608-
// If we haven't seen this library yet and we're targeting Windows, we need
7609-
// to queue up a work item to produce the DLL import library for this.
7610-
const gop = try comp.windows_libs.getOrPut(comp.gpa, lib_name);
7611-
if (gop.found_existing) return;
7612-
{
7613-
errdefer _ = comp.windows_libs.pop();
7614-
gop.key_ptr.* = try comp.gpa.dupe(u8, lib_name);
7615-
}
7616-
try comp.queueJob(.{ .windows_import_lib = gop.index });
7617-
}
7618-
76197605
/// This decides the optimization mode for all zig-provided libraries, including
76207606
/// compiler-rt, libcxx, libc, libunwind, etc.
76217607
pub fn compilerRtOptMode(comp: Compilation) std.builtin.OptimizeMode {

src/Sema.zig

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

9412-
/// Given a library name, examines if the library name should end up in
9413-
/// `link.File.Options.windows_libs` table (for example, libc is always
9414-
/// specified via dedicated flag `link_libc` instead),
9415-
/// and puts it there if it doesn't exist.
9416-
/// It also dupes the library name which can then be saved as part of the
9417-
/// respective `Decl` (either `ExternFn` or `Var`).
9418-
/// The liveness of the duped library name is tied to liveness of `Zcu`.
9419-
/// To deallocate, call `deinit` on the respective `Decl` (`ExternFn` or `Var`).
94209412
pub fn handleExternLibName(
94219413
sema: *Sema,
94229414
block: *Block,
@@ -9466,11 +9458,6 @@ pub fn handleExternLibName(
94669458
.{ lib_name, lib_name },
94679459
);
94689460
}
9469-
comp.addLinkLib(lib_name) catch |err| {
9470-
return sema.fail(block, src_loc, "unable to add link lib '{s}': {s}", .{
9471-
lib_name, @errorName(err),
9472-
});
9473-
};
94749461
}
94759462
}
94769463

src/libs/mingw.zig

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,6 +1014,7 @@ const mingw32_winpthreads_src = [_][]const u8{
10141014
"winpthreads" ++ path.sep_str ++ "thread.c",
10151015
};
10161016

1017+
// Note: kernel32 and ntdll are always linked even without targeting MinGW-w64.
10171018
pub const always_link_libs = [_][]const u8{
10181019
"api-ms-win-crt-conio-l1-1-0",
10191020
"api-ms-win-crt-convert-l1-1-0",
@@ -1031,8 +1032,6 @@ pub const always_link_libs = [_][]const u8{
10311032
"api-ms-win-crt-time-l1-1-0",
10321033
"api-ms-win-crt-utility-l1-1-0",
10331034
"advapi32",
1034-
"kernel32",
1035-
"ntdll",
10361035
"shell32",
10371036
"user32",
10381037
};

src/main.zig

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
306306
return jitCmd(gpa, arena, cmd_args, .{
307307
.cmd_name = "resinator",
308308
.root_src_path = "resinator/main.zig",
309+
.windows_libs = &.{"advapi32"},
309310
.depend_on_aro = true,
310311
.prepend_zig_lib_dir_path = true,
311312
.server = use_server,
@@ -3631,7 +3632,6 @@ fn buildOutputType(
36313632
} else if (target.os.tag == .windows) {
36323633
try test_exec_args.appendSlice(arena, &.{
36333634
"--subsystem", "console",
3634-
"-lkernel32", "-lntdll",
36353635
});
36363636
}
36373637

@@ -3845,7 +3845,8 @@ fn createModule(
38453845
.only_compiler_rt => continue,
38463846
}
38473847

3848-
if (target.isMinGW()) {
3848+
// We currently prefer import libraries provided by MinGW-w64 even for MSVC.
3849+
if (target.os.tag == .windows) {
38493850
const exists = mingw.libExists(arena, target, create_module.dirs.zig_lib, lib_name) catch |err| {
38503851
fatal("failed to check zig installation for DLL import libs: {s}", .{
38513852
@errorName(err),
@@ -5221,6 +5222,12 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
52215222

52225223
try root_mod.deps.put(arena, "@build", build_mod);
52235224

5225+
var windows_libs: std.StringArrayHashMapUnmanaged(void) = .empty;
5226+
5227+
if (resolved_target.result.os.tag == .windows) {
5228+
try windows_libs.put(arena, "advapi32", {});
5229+
}
5230+
52245231
const comp = Compilation.create(gpa, arena, .{
52255232
.dirs = dirs,
52265233
.root_name = "build",
@@ -5242,6 +5249,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
52425249
.cache_mode = .whole,
52435250
.reference_trace = reference_trace,
52445251
.debug_compile_errors = debug_compile_errors,
5252+
.windows_lib_names = windows_libs.keys(),
52455253
}) catch |err| {
52465254
fatal("unable to create compilation: {s}", .{@errorName(err)});
52475255
};
@@ -5345,6 +5353,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
53455353
const JitCmdOptions = struct {
53465354
cmd_name: []const u8,
53475355
root_src_path: []const u8,
5356+
windows_libs: []const []const u8 = &.{},
53485357
prepend_zig_lib_dir_path: bool = false,
53495358
prepend_global_cache_path: bool = false,
53505359
prepend_zig_exe_path: bool = false,
@@ -5461,6 +5470,13 @@ fn jitCmd(
54615470
try root_mod.deps.put(arena, "aro", aro_mod);
54625471
}
54635472

5473+
var windows_libs: std.StringArrayHashMapUnmanaged(void) = .empty;
5474+
5475+
if (resolved_target.result.os.tag == .windows) {
5476+
try windows_libs.ensureUnusedCapacity(arena, options.windows_libs.len);
5477+
for (options.windows_libs) |lib| windows_libs.putAssumeCapacity(lib, {});
5478+
}
5479+
54645480
const comp = Compilation.create(gpa, arena, .{
54655481
.dirs = dirs,
54665482
.root_name = options.cmd_name,
@@ -5471,6 +5487,7 @@ fn jitCmd(
54715487
.self_exe_path = self_exe_path,
54725488
.thread_pool = &thread_pool,
54735489
.cache_mode = .whole,
5490+
.windows_lib_names = windows_libs.keys(),
54745491
}) catch |err| {
54755492
fatal("unable to create compilation: {s}", .{@errorName(err)});
54765493
};

test/standalone/simple/build.zig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ 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+
5357
_ = exe.getEmittedBin();
5458

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

73+
if (resolved_target.result.os.tag == .windows) {
74+
exe.root_module.linkSystemLibrary("advapi32", .{});
75+
}
76+
6977
const run = b.addRunArtifact(exe);
7078
step.dependOn(&run.step);
7179
}

test/standalone/windows_argv/build.zig

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

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

test/standalone/windows_bat_args/build.zig

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

31+
test_exe.root_module.linkSystemLibrary("advapi32", .{});
32+
3133
const run = b.addRunArtifact(test_exe);
3234
run.addArtifactArg(echo_args);
3335
run.expectExitCode(0);
@@ -44,6 +46,8 @@ pub fn build(b: *std.Build) !void {
4446
}),
4547
});
4648

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

test/standalone/windows_spawn/build.zig

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

31+
main.root_module.linkSystemLibrary("advapi32", .{});
32+
3133
const run = b.addRunArtifact(main);
3234
run.addArtifactArg(hello);
3335
run.expectExitCode(0);

0 commit comments

Comments
 (0)