Skip to content

Commit b31a03f

Browse files
committed
Let CRT take care of the entry point for wWinMain if libc is linked
Fixes #7852 Before, the modified test would fail with: ``` error: lld-link: undefined symbol: wWinMain note: referenced by C:\Users\Ryan\Programming\Zig\zig-x86_64-windows-0.15.1\lib\libc\mingw\crt\crtexewin.c:66 note: libmingw32.lib(ucrtexewin.obj):(wmain) ```
1 parent be4eaed commit b31a03f

File tree

4 files changed

+90
-0
lines changed

4 files changed

+90
-0
lines changed

lib/std/start.zig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ comptime {
6161
} else if (!@typeInfo(@TypeOf(root.main)).@"fn".calling_convention.eql(.c)) {
6262
@export(&main, .{ .name = "main" });
6363
}
64+
} else if (native_os == .windows and builtin.link_libc and @hasDecl(root, "wWinMain")) {
65+
if (!@typeInfo(@TypeOf(root.wWinMain)).@"fn".calling_convention.eql(.c)) {
66+
@export(&wWinMain, .{ .name = "wWinMain" });
67+
}
6468
} else if (native_os == .windows) {
6569
if (!@hasDecl(root, "WinMain") and !@hasDecl(root, "WinMainCRTStartup") and
6670
!@hasDecl(root, "wWinMain") and !@hasDecl(root, "wWinMainCRTStartup"))
@@ -527,6 +531,10 @@ fn wWinMainCRTStartup() callconv(.withStackAlign(.c, 1)) noreturn {
527531
std.os.windows.ntdll.RtlExitUserProcess(@as(std.os.windows.UINT, @bitCast(result)));
528532
}
529533

534+
fn wWinMain(hInstance: *anyopaque, hPrevInstance: ?*anyopaque, pCmdLine: [*:0]u16, nCmdShow: c_int) callconv(.c) c_int {
535+
return root.wWinMain(@ptrCast(hInstance), @ptrCast(hPrevInstance), pCmdLine, @intCast(nCmdShow));
536+
}
537+
530538
fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.c) noreturn {
531539
// We're not ready to panic until thread local storage is initialized.
532540
@setRuntimeSafety(false);

test/standalone/windows_entry_points/build.zig

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,66 @@ pub fn build(b: *std.Build) void {
7777
_ = exe.getEmittedBin();
7878
test_step.dependOn(&exe.step);
7979
}
80+
81+
{
82+
const exe = b.addExecutable(.{
83+
.name = "zig_main",
84+
.root_module = b.createModule(.{
85+
.root_source_file = b.path("main.zig"),
86+
.target = target,
87+
.optimize = .Debug,
88+
}),
89+
});
90+
91+
_ = exe.getEmittedBin();
92+
test_step.dependOn(&exe.step);
93+
}
94+
95+
{
96+
const exe = b.addExecutable(.{
97+
.name = "zig_main_link_libc",
98+
.root_module = b.createModule(.{
99+
.root_source_file = b.path("main.zig"),
100+
.target = target,
101+
.optimize = .Debug,
102+
.link_libc = true,
103+
}),
104+
});
105+
106+
_ = exe.getEmittedBin();
107+
test_step.dependOn(&exe.step);
108+
}
109+
110+
{
111+
const exe = b.addExecutable(.{
112+
.name = "zig_wwinmain",
113+
.root_module = b.createModule(.{
114+
.root_source_file = b.path("wwinmain.zig"),
115+
.target = target,
116+
.optimize = .Debug,
117+
}),
118+
});
119+
exe.mingw_unicode_entry_point = true;
120+
// Note: `exe.subsystem = .windows;` is not necessary
121+
122+
_ = exe.getEmittedBin();
123+
test_step.dependOn(&exe.step);
124+
}
125+
126+
{
127+
const exe = b.addExecutable(.{
128+
.name = "zig_wwinmain_link_libc",
129+
.root_module = b.createModule(.{
130+
.root_source_file = b.path("wwinmain.zig"),
131+
.target = target,
132+
.optimize = .Debug,
133+
.link_libc = true,
134+
}),
135+
});
136+
exe.mingw_unicode_entry_point = true;
137+
// Note: `exe.subsystem = .windows;` is not necessary
138+
139+
_ = exe.getEmittedBin();
140+
test_step.dependOn(&exe.step);
141+
}
80142
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const std = @import("std");
2+
3+
pub fn main() void {
4+
std.debug.print("hello from Zig main\n", .{});
5+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const std = @import("std");
2+
3+
pub fn wWinMain(
4+
inst: std.os.windows.HINSTANCE,
5+
prev: ?std.os.windows.HINSTANCE,
6+
cmd_line: std.os.windows.LPWSTR,
7+
cmd_show: c_int,
8+
) std.os.windows.INT {
9+
_ = inst;
10+
_ = prev;
11+
_ = cmd_line;
12+
_ = cmd_show;
13+
std.debug.print("hello from Zig wWinMain\n", .{});
14+
return 0;
15+
}

0 commit comments

Comments
 (0)