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.
This commit is contained in:
Carl Åstholm 2025-09-05 17:45:22 +02:00
parent 74900e938a
commit 075d300342
2 changed files with 9 additions and 38 deletions

View File

@ -6,32 +6,6 @@ const root = @import("root");
pub const assembly = @import("builtin/assembly.zig"); pub const assembly = @import("builtin/assembly.zig");
/// `explicit_subsystem` is missing when the subsystem is automatically detected,
/// so Zig standard library has the subsystem detection logic here. This should generally be
/// used rather than `explicit_subsystem`.
/// On non-Windows targets, this is `null`.
pub const subsystem: ?std.Target.SubSystem = blk: {
if (@hasDecl(builtin, "explicit_subsystem")) break :blk builtin.explicit_subsystem;
switch (builtin.os.tag) {
.windows => {
if (builtin.is_test) {
break :blk std.Target.SubSystem.Console;
}
if (@hasDecl(root, "main") or
@hasDecl(root, "WinMain") or
@hasDecl(root, "wWinMain") or
@hasDecl(root, "WinMainCRTStartup") or
@hasDecl(root, "wWinMainCRTStartup"))
{
break :blk std.Target.SubSystem.Windows;
} else {
break :blk std.Target.SubSystem.Console;
}
},
else => break :blk null,
}
};
/// This data structure is used by the Zig language code generation and /// This data structure is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation. /// therefore must be kept in sync with the compiler implementation.
pub const StackTrace = struct { pub const StackTrace = struct {

View File

@ -734,24 +734,21 @@ pub fn call_wWinMain() std.os.windows.INT {
// - u32 in PEB.ProcessParameters.dwShowWindow // - u32 in PEB.ProcessParameters.dwShowWindow
// Since STARTUPINFO is the bottleneck for the allowed values, we use `u16` as the // Since STARTUPINFO is the bottleneck for the allowed values, we use `u16` as the
// type which can coerce into i32/c_int/u32 depending on how the user defines their wWinMain // type which can coerce into i32/c_int/u32 depending on how the user defines their wWinMain
// (the Win32 docs show wWinMain with `int` as the type for nCmdShow). // (the Win32 docs show wWinMain with `int` as the type for nShowCmd).
const nCmdShow: u16 = nCmdShow: { const nShowCmd: u16 = nShowCmd: {
// This makes Zig match the nCmdShow behavior of a C program with a WinMain symbol: // This makes Zig match the nShowCmd behavior of a C program with a WinMain symbol:
// - With STARTF_USESHOWWINDOW set in STARTUPINFO.dwFlags of the CreateProcess call: // - With STARTF_USESHOWWINDOW set in STARTUPINFO.dwFlags of the CreateProcess call:
// - Compiled with subsystem:console -> nCmdShow is always SW_SHOWDEFAULT // - nShowCmd is STARTUPINFO.wShowWindow from the parent CreateProcess call
// - Compiled with subsystem:windows -> nCmdShow is STARTUPINFO.wShowWindow from
// the parent CreateProcess call
// - With STARTF_USESHOWWINDOW unset: // - With STARTF_USESHOWWINDOW unset:
// - nCmdShow is always SW_SHOWDEFAULT // - nShowCmd is always SW_SHOWDEFAULT
const SW_SHOWDEFAULT = 10; const SW_SHOWDEFAULT = 10;
const STARTF_USESHOWWINDOW = 1; const STARTF_USESHOWWINDOW = 1;
// root having a wWinMain means that std.builtin.subsystem will always have a non-null value. if (peb.ProcessParameters.dwFlags & STARTF_USESHOWWINDOW != 0) {
if (std.builtin.subsystem.? == .Windows and peb.ProcessParameters.dwFlags & STARTF_USESHOWWINDOW != 0) { break :nShowCmd @truncate(peb.ProcessParameters.dwShowWindow);
break :nCmdShow @truncate(peb.ProcessParameters.dwShowWindow);
} }
break :nCmdShow SW_SHOWDEFAULT; break :nShowCmd SW_SHOWDEFAULT;
}; };
// second parameter hPrevInstance, MSDN: "This parameter is always NULL" // second parameter hPrevInstance, MSDN: "This parameter is always NULL"
return root.wWinMain(hInstance, null, lpCmdLine, nCmdShow); return root.wWinMain(hInstance, null, lpCmdLine, nShowCmd);
} }