authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-06-11 14:41:42+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-07-06 01:00:18+02:00
logb461d07a5464aec86c533434dab0b58edfffb331
treed3e19fc63623fb765ff08757c069e27d915ef66e
parent044ccf4138f8b027be01c95ad759d5302e2ff39d

Sema: Stop adding Windows implib link inputs for `extern "..."` syntax.

Closes #23971.

10 files changed, 75 insertions(+), 46 deletions(-)

build.zig+20
...@@ -450,6 +450,7 @@ pub fn build(b: *std.Build) !void {...@@ -450,6 +450,7 @@ pub fn build(b: *std.Build) !void {
450 .desc = "Run the behavior tests",450 .desc = "Run the behavior tests",
451 .optimize_modes = optimization_modes,451 .optimize_modes = optimization_modes,
452 .include_paths = &.{},452 .include_paths = &.{},
453 .windows_libs = &.{},
453 .skip_single_threaded = skip_single_threaded,454 .skip_single_threaded = skip_single_threaded,
454 .skip_non_native = skip_non_native,455 .skip_non_native = skip_non_native,
455 .skip_freebsd = skip_freebsd,456 .skip_freebsd = skip_freebsd,
...@@ -472,6 +473,7 @@ pub fn build(b: *std.Build) !void {...@@ -472,6 +473,7 @@ pub fn build(b: *std.Build) !void {
472 .desc = "Run the @cImport tests",473 .desc = "Run the @cImport tests",
473 .optimize_modes = optimization_modes,474 .optimize_modes = optimization_modes,
474 .include_paths = &.{"test/c_import"},475 .include_paths = &.{"test/c_import"},
476 .windows_libs = &.{},
475 .skip_single_threaded = true,477 .skip_single_threaded = true,
476 .skip_non_native = skip_non_native,478 .skip_non_native = skip_non_native,
477 .skip_freebsd = skip_freebsd,479 .skip_freebsd = skip_freebsd,
...@@ -492,6 +494,7 @@ pub fn build(b: *std.Build) !void {...@@ -492,6 +494,7 @@ pub fn build(b: *std.Build) !void {
492 .desc = "Run the compiler_rt tests",494 .desc = "Run the compiler_rt tests",
493 .optimize_modes = optimization_modes,495 .optimize_modes = optimization_modes,
494 .include_paths = &.{},496 .include_paths = &.{},
497 .windows_libs = &.{},
495 .skip_single_threaded = true,498 .skip_single_threaded = true,
496 .skip_non_native = skip_non_native,499 .skip_non_native = skip_non_native,
497 .skip_freebsd = skip_freebsd,500 .skip_freebsd = skip_freebsd,
...@@ -513,6 +516,7 @@ pub fn build(b: *std.Build) !void {...@@ -513,6 +516,7 @@ pub fn build(b: *std.Build) !void {
513 .desc = "Run the zigc tests",516 .desc = "Run the zigc tests",
514 .optimize_modes = optimization_modes,517 .optimize_modes = optimization_modes,
515 .include_paths = &.{},518 .include_paths = &.{},
519 .windows_libs = &.{},
516 .skip_single_threaded = true,520 .skip_single_threaded = true,
517 .skip_non_native = skip_non_native,521 .skip_non_native = skip_non_native,
518 .skip_freebsd = skip_freebsd,522 .skip_freebsd = skip_freebsd,
...@@ -534,6 +538,12 @@ pub fn build(b: *std.Build) !void {...@@ -534,6 +538,12 @@ pub fn build(b: *std.Build) !void {
534 .desc = "Run the standard library tests",538 .desc = "Run the standard library tests",
535 .optimize_modes = optimization_modes,539 .optimize_modes = optimization_modes,
536 .include_paths = &.{},540 .include_paths = &.{},
541 .windows_libs = &.{
542 "advapi32",
543 "crypt32",
544 "iphlpapi",
545 "ws2_32",
546 },
537 .skip_single_threaded = skip_single_threaded,547 .skip_single_threaded = skip_single_threaded,
538 .skip_non_native = skip_non_native,548 .skip_non_native = skip_non_native,
539 .skip_freebsd = skip_freebsd,549 .skip_freebsd = skip_freebsd,
...@@ -731,6 +741,12 @@ fn addCompilerMod(b: *std.Build, options: AddCompilerModOptions) *std.Build.Modu...@@ -731,6 +741,12 @@ fn addCompilerMod(b: *std.Build, options: AddCompilerModOptions) *std.Build.Modu
731 compiler_mod.addImport("aro", aro_mod);741 compiler_mod.addImport("aro", aro_mod);
732 compiler_mod.addImport("aro_translate_c", aro_translate_c_mod);742 compiler_mod.addImport("aro_translate_c", aro_translate_c_mod);
733743
744 if (options.target.result.os.tag == .windows) {
745 compiler_mod.linkSystemLibrary("advapi32", .{});
746 compiler_mod.linkSystemLibrary("crypt32", .{});
747 compiler_mod.linkSystemLibrary("ws2_32", .{});
748 }
749
734 return compiler_mod;750 return compiler_mod;
735}751}
736752
...@@ -1428,6 +1444,10 @@ fn generateLangRef(b: *std.Build) std.Build.LazyPath {...@@ -1428,6 +1444,10 @@ fn generateLangRef(b: *std.Build) std.Build.LazyPath {
1428 }),1444 }),
1429 });1445 });
14301446
1447 if (b.graph.host.result.os.tag == .windows) {
1448 doctest_exe.root_module.linkSystemLibrary("advapi32", .{});
1449 }
1450
1431 var dir = b.build_root.handle.openDir("doc/langref", .{ .iterate = true }) catch |err| {1451 var dir = b.build_root.handle.openDir("doc/langref", .{ .iterate = true }) catch |err| {
1432 std.debug.panic("unable to open '{}doc/langref' directory: {s}", .{1452 std.debug.panic("unable to open '{}doc/langref' directory: {s}", .{
1433 b.build_root, @errorName(err),1453 b.build_root, @errorName(err),
src/Compilation.zig+10-29
...@@ -2070,12 +2070,8 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2070,12 +2070,8 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2070 .emit_docs = try options.emit_docs.resolve(arena, &options, .docs),2070 .emit_docs = try options.emit_docs.resolve(arena, &options, .docs),
2071 };2071 };
20722072
2073 errdefer {2073 comp.windows_libs = try std.StringArrayHashMapUnmanaged(void).init(gpa, options.windows_lib_names, &.{});
2074 for (comp.windows_libs.keys()) |windows_lib| gpa.free(windows_lib);2074 errdefer comp.windows_libs.deinit(gpa);
2075 comp.windows_libs.deinit(gpa);
2076 }
2077 try comp.windows_libs.ensureUnusedCapacity(gpa, options.windows_lib_names.len);
2078 for (options.windows_lib_names) |windows_lib| comp.windows_libs.putAssumeCapacity(try gpa.dupe(u8, windows_lib), {});
20792075
2080 // Prevent some footguns by making the "any" fields of config reflect2076 // Prevent some footguns by making the "any" fields of config reflect
2081 // the default Module settings.2077 // the default Module settings.
...@@ -2306,6 +2302,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2306,6 +2302,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
23062302
2307 if (comp.emit_bin != null and target.ofmt != .c) {2303 if (comp.emit_bin != null and target.ofmt != .c) {
2308 if (!comp.skip_linker_dependencies) {2304 if (!comp.skip_linker_dependencies) {
2305 // These DLLs are always loaded into every Windows process.
2306 if (target.os.tag == .windows and is_exe_or_dyn_lib) {
2307 try comp.windows_libs.ensureUnusedCapacity(gpa, 2);
2308 comp.windows_libs.putAssumeCapacity("kernel32", {});
2309 comp.windows_libs.putAssumeCapacity("ntdll", {});
2310 }
2311
2309 // If we need to build libc for the target, add work items for it.2312 // If we need to build libc for the target, add work items for it.
2310 // We go through the work queue so that building can be done in parallel.2313 // We go through the work queue so that building can be done in parallel.
2311 // If linking against host libc installation, instead queue up jobs2314 // If linking against host libc installation, instead queue up jobs
...@@ -2399,7 +2402,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2399,7 +2402,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
23992402
2400 // When linking mingw-w64 there are some import libs we always need.2403 // When linking mingw-w64 there are some import libs we always need.
2401 try comp.windows_libs.ensureUnusedCapacity(gpa, mingw.always_link_libs.len);2404 try comp.windows_libs.ensureUnusedCapacity(gpa, mingw.always_link_libs.len);
2402 for (mingw.always_link_libs) |name| comp.windows_libs.putAssumeCapacity(try gpa.dupe(u8, name), {});2405 for (mingw.always_link_libs) |name| comp.windows_libs.putAssumeCapacity(name, {});
2403 } else {2406 } else {
2404 return error.LibCUnavailable;2407 return error.LibCUnavailable;
2405 }2408 }
...@@ -2497,7 +2500,6 @@ pub fn destroy(comp: *Compilation) void {...@@ -2497,7 +2500,6 @@ pub fn destroy(comp: *Compilation) void {
2497 comp.c_object_work_queue.deinit();2500 comp.c_object_work_queue.deinit();
2498 comp.win32_resource_work_queue.deinit();2501 comp.win32_resource_work_queue.deinit();
24992502
2500 for (comp.windows_libs.keys()) |windows_lib| gpa.free(windows_lib);
2501 comp.windows_libs.deinit(gpa);2503 comp.windows_libs.deinit(gpa);
25022504
2503 {2505 {
...@@ -7599,27 +7601,6 @@ fn getCrtPathsInner(...@@ -7599,27 +7601,6 @@ fn getCrtPathsInner(
7599 };7601 };
7600}7602}
76017603
7602pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void {
7603 // Avoid deadlocking on building import libs such as kernel32.lib
7604 // This can happen when the user uses `build-exe foo.obj -lkernel32` and
7605 // then when we create a sub-Compilation for zig libc, it also tries to
7606 // build kernel32.lib.
7607 if (comp.skip_linker_dependencies) return;
7608 const target = &comp.root_mod.resolved_target.result;
7609 if (target.os.tag != .windows or target.ofmt == .c) return;
7610
7611 // This happens when an `extern "foo"` function is referenced.
7612 // If we haven't seen this library yet and we're targeting Windows, we need
7613 // to queue up a work item to produce the DLL import library for this.
7614 const gop = try comp.windows_libs.getOrPut(comp.gpa, lib_name);
7615 if (gop.found_existing) return;
7616 {
7617 errdefer _ = comp.windows_libs.pop();
7618 gop.key_ptr.* = try comp.gpa.dupe(u8, lib_name);
7619 }
7620 try comp.queueJob(.{ .windows_import_lib = gop.index });
7621}
7622
7623/// This decides the optimization mode for all zig-provided libraries, including7604/// This decides the optimization mode for all zig-provided libraries, including
7624/// compiler-rt, libcxx, libc, libunwind, etc.7605/// compiler-rt, libcxx, libc, libunwind, etc.
7625pub fn compilerRtOptMode(comp: Compilation) std.builtin.OptimizeMode {7606pub fn compilerRtOptMode(comp: Compilation) std.builtin.OptimizeMode {
src/Sema.zig-13
...@@ -9418,14 +9418,6 @@ fn resolveGenericBody(...@@ -9418,14 +9418,6 @@ fn resolveGenericBody(
9418 return sema.resolveConstDefinedValue(block, src, result, reason);9418 return sema.resolveConstDefinedValue(block, src, result, reason);
9419}9419}
94209420
9421/// Given a library name, examines if the library name should end up in
9422/// `link.File.Options.windows_libs` table (for example, libc is always
9423/// specified via dedicated flag `link_libc` instead),
9424/// and puts it there if it doesn't exist.
9425/// It also dupes the library name which can then be saved as part of the
9426/// respective `Decl` (either `ExternFn` or `Var`).
9427/// The liveness of the duped library name is tied to liveness of `Zcu`.
9428/// To deallocate, call `deinit` on the respective `Decl` (`ExternFn` or `Var`).
9429pub fn handleExternLibName(9421pub fn handleExternLibName(
9430 sema: *Sema,9422 sema: *Sema,
9431 block: *Block,9423 block: *Block,
...@@ -9475,11 +9467,6 @@ pub fn handleExternLibName(...@@ -9475,11 +9467,6 @@ pub fn handleExternLibName(
9475 .{ lib_name, lib_name },9467 .{ lib_name, lib_name },
9476 );9468 );
9477 }9469 }
9478 comp.addLinkLib(lib_name) catch |err| {
9479 return sema.fail(block, src_loc, "unable to add link lib '{s}': {s}", .{
9480 lib_name, @errorName(err),
9481 });
9482 };
9483 }9470 }
9484}9471}
94859472
src/libs/mingw.zig+1-2
...@@ -1012,6 +1012,7 @@ const mingw32_winpthreads_src = [_][]const u8{...@@ -1012,6 +1012,7 @@ const mingw32_winpthreads_src = [_][]const u8{
1012 "winpthreads" ++ path.sep_str ++ "thread.c",1012 "winpthreads" ++ path.sep_str ++ "thread.c",
1013};1013};
10141014
1015// Note: kernel32 and ntdll are always linked even without targeting MinGW-w64.
1015pub const always_link_libs = [_][]const u8{1016pub const always_link_libs = [_][]const u8{
1016 "api-ms-win-crt-conio-l1-1-0",1017 "api-ms-win-crt-conio-l1-1-0",
1017 "api-ms-win-crt-convert-l1-1-0",1018 "api-ms-win-crt-convert-l1-1-0",
...@@ -1029,8 +1030,6 @@ pub const always_link_libs = [_][]const u8{...@@ -1029,8 +1030,6 @@ pub const always_link_libs = [_][]const u8{
1029 "api-ms-win-crt-time-l1-1-0",1030 "api-ms-win-crt-time-l1-1-0",
1030 "api-ms-win-crt-utility-l1-1-0",1031 "api-ms-win-crt-utility-l1-1-0",
1031 "advapi32",1032 "advapi32",
1032 "kernel32",
1033 "ntdll",
1034 "shell32",1033 "shell32",
1035 "user32",1034 "user32",
1036};1035};
src/main.zig+19-2
...@@ -306,6 +306,7 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -306,6 +306,7 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
306 return jitCmd(gpa, arena, cmd_args, .{306 return jitCmd(gpa, arena, cmd_args, .{
307 .cmd_name = "resinator",307 .cmd_name = "resinator",
308 .root_src_path = "resinator/main.zig",308 .root_src_path = "resinator/main.zig",
309 .windows_libs = &.{"advapi32"},
309 .depend_on_aro = true,310 .depend_on_aro = true,
310 .prepend_zig_lib_dir_path = true,311 .prepend_zig_lib_dir_path = true,
311 .server = use_server,312 .server = use_server,
...@@ -3631,7 +3632,6 @@ fn buildOutputType(...@@ -3631,7 +3632,6 @@ fn buildOutputType(
3631 } else if (target.os.tag == .windows) {3632 } else if (target.os.tag == .windows) {
3632 try test_exec_args.appendSlice(arena, &.{3633 try test_exec_args.appendSlice(arena, &.{
3633 "--subsystem", "console",3634 "--subsystem", "console",
3634 "-lkernel32", "-lntdll",
3635 });3635 });
3636 }3636 }
36373637
...@@ -3845,7 +3845,8 @@ fn createModule(...@@ -3845,7 +3845,8 @@ fn createModule(
3845 .only_compiler_rt => continue,3845 .only_compiler_rt => continue,
3846 }3846 }
38473847
3848 if (target.isMinGW()) {3848 // We currently prefer import libraries provided by MinGW-w64 even for MSVC.
3849 if (target.os.tag == .windows) {
3849 const exists = mingw.libExists(arena, target, create_module.dirs.zig_lib, lib_name) catch |err| {3850 const exists = mingw.libExists(arena, target, create_module.dirs.zig_lib, lib_name) catch |err| {
3850 fatal("failed to check zig installation for DLL import libs: {s}", .{3851 fatal("failed to check zig installation for DLL import libs: {s}", .{
3851 @errorName(err),3852 @errorName(err),
...@@ -5221,6 +5222,12 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -5221,6 +5222,12 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
52215222
5222 try root_mod.deps.put(arena, "@build", build_mod);5223 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
5224 const comp = Compilation.create(gpa, arena, .{5231 const comp = Compilation.create(gpa, arena, .{
5225 .dirs = dirs,5232 .dirs = dirs,
5226 .root_name = "build",5233 .root_name = "build",
...@@ -5242,6 +5249,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -5242,6 +5249,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
5242 .cache_mode = .whole,5249 .cache_mode = .whole,
5243 .reference_trace = reference_trace,5250 .reference_trace = reference_trace,
5244 .debug_compile_errors = debug_compile_errors,5251 .debug_compile_errors = debug_compile_errors,
5252 .windows_lib_names = windows_libs.keys(),
5245 }) catch |err| {5253 }) catch |err| {
5246 fatal("unable to create compilation: {s}", .{@errorName(err)});5254 fatal("unable to create compilation: {s}", .{@errorName(err)});
5247 };5255 };
...@@ -5345,6 +5353,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -5345,6 +5353,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
5345const JitCmdOptions = struct {5353const JitCmdOptions = struct {
5346 cmd_name: []const u8,5354 cmd_name: []const u8,
5347 root_src_path: []const u8,5355 root_src_path: []const u8,
5356 windows_libs: []const []const u8 = &.{},
5348 prepend_zig_lib_dir_path: bool = false,5357 prepend_zig_lib_dir_path: bool = false,
5349 prepend_global_cache_path: bool = false,5358 prepend_global_cache_path: bool = false,
5350 prepend_zig_exe_path: bool = false,5359 prepend_zig_exe_path: bool = false,
...@@ -5461,6 +5470,13 @@ fn jitCmd(...@@ -5461,6 +5470,13 @@ fn jitCmd(
5461 try root_mod.deps.put(arena, "aro", aro_mod);5470 try root_mod.deps.put(arena, "aro", aro_mod);
5462 }5471 }
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
5464 const comp = Compilation.create(gpa, arena, .{5480 const comp = Compilation.create(gpa, arena, .{
5465 .dirs = dirs,5481 .dirs = dirs,
5466 .root_name = options.cmd_name,5482 .root_name = options.cmd_name,
...@@ -5471,6 +5487,7 @@ fn jitCmd(...@@ -5471,6 +5487,7 @@ fn jitCmd(
5471 .self_exe_path = self_exe_path,5487 .self_exe_path = self_exe_path,
5472 .thread_pool = &thread_pool,5488 .thread_pool = &thread_pool,
5473 .cache_mode = .whole,5489 .cache_mode = .whole,
5490 .windows_lib_names = windows_libs.keys(),
5474 }) catch |err| {5491 }) catch |err| {
5475 fatal("unable to create compilation: {s}", .{@errorName(err)});5492 fatal("unable to create compilation: {s}", .{@errorName(err)});
5476 };5493 };
test/standalone/simple/build.zig+8
...@@ -50,6 +50,10 @@ pub fn build(b: *std.Build) void {...@@ -50,6 +50,10 @@ pub fn build(b: *std.Build) void {
50 });50 });
51 if (case.link_libc) exe.root_module.link_libc = true;51 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
53 _ = exe.getEmittedBin();57 _ = exe.getEmittedBin();
5458
55 step.dependOn(&exe.step);59 step.dependOn(&exe.step);
...@@ -66,6 +70,10 @@ pub fn build(b: *std.Build) void {...@@ -66,6 +70,10 @@ pub fn build(b: *std.Build) void {
66 });70 });
67 if (case.link_libc) exe.root_module.link_libc = true;71 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
69 const run = b.addRunArtifact(exe);77 const run = b.addRunArtifact(exe);
70 step.dependOn(&run.step);78 step.dependOn(&run.step);
71 }79 }
test/standalone/windows_argv/build.zig+2
...@@ -47,6 +47,8 @@ pub fn build(b: *std.Build) !void {...@@ -47,6 +47,8 @@ pub fn build(b: *std.Build) !void {
47 }),47 }),
48 });48 });
4949
50 fuzz.root_module.linkSystemLibrary("advapi32", .{});
51
50 const fuzz_max_iterations = b.option(u64, "iterations", "The max fuzz iterations (default: 100)") orelse 100;52 const fuzz_max_iterations = b.option(u64, "iterations", "The max fuzz iterations (default: 100)") orelse 100;
51 const fuzz_iterations_arg = std.fmt.allocPrint(b.allocator, "{}", .{fuzz_max_iterations}) catch @panic("oom");53 const fuzz_iterations_arg = std.fmt.allocPrint(b.allocator, "{}", .{fuzz_max_iterations}) catch @panic("oom");
5254
test/standalone/windows_bat_args/build.zig+4
...@@ -28,6 +28,8 @@ pub fn build(b: *std.Build) !void {...@@ -28,6 +28,8 @@ pub fn build(b: *std.Build) !void {
28 }),28 }),
29 });29 });
3030
31 test_exe.root_module.linkSystemLibrary("advapi32", .{});
32
31 const run = b.addRunArtifact(test_exe);33 const run = b.addRunArtifact(test_exe);
32 run.addArtifactArg(echo_args);34 run.addArtifactArg(echo_args);
33 run.expectExitCode(0);35 run.expectExitCode(0);
...@@ -44,6 +46,8 @@ pub fn build(b: *std.Build) !void {...@@ -44,6 +46,8 @@ pub fn build(b: *std.Build) !void {
44 }),46 }),
45 });47 });
4648
49 fuzz.root_module.linkSystemLibrary("advapi32", .{});
50
47 const fuzz_max_iterations = b.option(u64, "iterations", "The max fuzz iterations (default: 100)") orelse 100;51 const fuzz_max_iterations = b.option(u64, "iterations", "The max fuzz iterations (default: 100)") orelse 100;
48 const fuzz_iterations_arg = std.fmt.allocPrint(b.allocator, "{}", .{fuzz_max_iterations}) catch @panic("oom");52 const fuzz_iterations_arg = std.fmt.allocPrint(b.allocator, "{}", .{fuzz_max_iterations}) catch @panic("oom");
4953
test/standalone/windows_spawn/build.zig+2
...@@ -28,6 +28,8 @@ pub fn build(b: *std.Build) void {...@@ -28,6 +28,8 @@ pub fn build(b: *std.Build) void {
28 }),28 }),
29 });29 });
3030
31 main.root_module.linkSystemLibrary("advapi32", .{});
32
31 const run = b.addRunArtifact(main);33 const run = b.addRunArtifact(main);
32 run.addArtifactArg(hello);34 run.addArtifactArg(hello);
33 run.expectExitCode(0);35 run.expectExitCode(0);
test/tests.zig+9
...@@ -2308,6 +2308,7 @@ const ModuleTestOptions = struct {...@@ -2308,6 +2308,7 @@ const ModuleTestOptions = struct {
2308 desc: []const u8,2308 desc: []const u8,
2309 optimize_modes: []const OptimizeMode,2309 optimize_modes: []const OptimizeMode,
2310 include_paths: []const []const u8,2310 include_paths: []const []const u8,
2311 windows_libs: []const []const u8,
2311 skip_single_threaded: bool,2312 skip_single_threaded: bool,
2312 skip_non_native: bool,2313 skip_non_native: bool,
2313 skip_freebsd: bool,2314 skip_freebsd: bool,
...@@ -2437,6 +2438,10 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {...@@ -2437,6 +2438,10 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
24372438
2438 for (options.include_paths) |include_path| these_tests.addIncludePath(b.path(include_path));2439 for (options.include_paths) |include_path| these_tests.addIncludePath(b.path(include_path));
24392440
2441 if (target.os.tag == .windows) {
2442 for (options.windows_libs) |lib| these_tests.linkSystemLibrary(lib);
2443 }
2444
2440 const qualified_name = b.fmt("{s}-{s}-{s}-{s}{s}{s}{s}{s}{s}{s}", .{2445 const qualified_name = b.fmt("{s}-{s}-{s}-{s}{s}{s}{s}{s}{s}{s}", .{
2441 options.name,2446 options.name,
2442 triple_txt,2447 triple_txt,
...@@ -2732,6 +2737,10 @@ pub fn addIncrementalTests(b: *std.Build, test_step: *Step) !void {...@@ -2732,6 +2737,10 @@ pub fn addIncrementalTests(b: *std.Build, test_step: *Step) !void {
2732 }),2737 }),
2733 });2738 });
27342739
2740 if (b.graph.host.result.os.tag == .windows) {
2741 incr_check.root_module.linkSystemLibrary("advapi32", .{});
2742 }
2743
2735 var dir = try b.build_root.handle.openDir("test/incremental", .{ .iterate = true });2744 var dir = try b.build_root.handle.openDir("test/incremental", .{ .iterate = true });
2736 defer dir.close();2745 defer dir.close();
27372746