authorgravatar for carl@astholm.seCarl Åstholm <carl@astholm.se> 2025-09-05 17:45:22+02:00
committergravatar for carl@astholm.seCarl Åstholm <carl@astholm.se> 2025-11-05 01:29:00+01:00
log075d300342afa72f5328c0ee4232151dd0968264
treef672c3949d01b2bafb4474523ecdea9a6a27759d
parent74900e938a8ea28b6ea7aa35924a2dee9818056b

Remove `std.builtin.subsystem`

The subsystem detection was flaky and often incorrect and was not actually needed by the compiler or standard library. The actual subsystem won't be known until at link time, so it doesn't make sense to try to determine it at compile time.

2 files changed, 9 insertions(+), 38 deletions(-)

lib/std/builtin.zig-26
......@@ -6,32 +6,6 @@ const root = @import("root");
66
77pub const assembly = @import("builtin/assembly.zig");
88
9/// `explicit_subsystem` is missing when the subsystem is automatically detected,
10/// so Zig standard library has the subsystem detection logic here. This should generally be
11/// used rather than `explicit_subsystem`.
12/// On non-Windows targets, this is `null`.
13pub const subsystem: ?std.Target.SubSystem = blk: {
14 if (@hasDecl(builtin, "explicit_subsystem")) break :blk builtin.explicit_subsystem;
15 switch (builtin.os.tag) {
16 .windows => {
17 if (builtin.is_test) {
18 break :blk std.Target.SubSystem.Console;
19 }
20 if (@hasDecl(root, "main") or
21 @hasDecl(root, "WinMain") or
22 @hasDecl(root, "wWinMain") or
23 @hasDecl(root, "WinMainCRTStartup") or
24 @hasDecl(root, "wWinMainCRTStartup"))
25 {
26 break :blk std.Target.SubSystem.Windows;
27 } else {
28 break :blk std.Target.SubSystem.Console;
29 }
30 },
31 else => break :blk null,
32 }
33};
34
359/// This data structure is used by the Zig language code generation and
3610/// therefore must be kept in sync with the compiler implementation.
3711pub const StackTrace = struct {
lib/std/start.zig+9-12
......@@ -734,24 +734,21 @@ pub fn call_wWinMain() std.os.windows.INT {
734734 // - u32 in PEB.ProcessParameters.dwShowWindow
735735 // Since STARTUPINFO is the bottleneck for the allowed values, we use `u16` as the
736736 // type which can coerce into i32/c_int/u32 depending on how the user defines their wWinMain
737 // (the Win32 docs show wWinMain with `int` as the type for nCmdShow).
738 const nCmdShow: u16 = nCmdShow: {
739 // This makes Zig match the nCmdShow behavior of a C program with a WinMain symbol:
737 // (the Win32 docs show wWinMain with `int` as the type for nShowCmd).
738 const nShowCmd: u16 = nShowCmd: {
739 // This makes Zig match the nShowCmd behavior of a C program with a WinMain symbol:
740740 // - With STARTF_USESHOWWINDOW set in STARTUPINFO.dwFlags of the CreateProcess call:
741 // - Compiled with subsystem:console -> nCmdShow is always SW_SHOWDEFAULT
742 // - Compiled with subsystem:windows -> nCmdShow is STARTUPINFO.wShowWindow from
743 // the parent CreateProcess call
741 // - nShowCmd is STARTUPINFO.wShowWindow from the parent CreateProcess call
744742 // - With STARTF_USESHOWWINDOW unset:
745 // - nCmdShow is always SW_SHOWDEFAULT
743 // - nShowCmd is always SW_SHOWDEFAULT
746744 const SW_SHOWDEFAULT = 10;
747745 const STARTF_USESHOWWINDOW = 1;
748 // root having a wWinMain means that std.builtin.subsystem will always have a non-null value.
749 if (std.builtin.subsystem.? == .Windows and peb.ProcessParameters.dwFlags & STARTF_USESHOWWINDOW != 0) {
750 break :nCmdShow @truncate(peb.ProcessParameters.dwShowWindow);
746 if (peb.ProcessParameters.dwFlags & STARTF_USESHOWWINDOW != 0) {
747 break :nShowCmd @truncate(peb.ProcessParameters.dwShowWindow);
751748 }
752 break :nCmdShow SW_SHOWDEFAULT;
749 break :nShowCmd SW_SHOWDEFAULT;
753750 };
754751
755752 // second parameter hPrevInstance, MSDN: "This parameter is always NULL"
756 return root.wWinMain(hInstance, null, lpCmdLine, nCmdShow);
753 return root.wWinMain(hInstance, null, lpCmdLine, nShowCmd);
757754}