build: default to MSVC ABI on Windows

Zig defaults to the GNU ABI on Windows, which produces COFF objects
with invalid COMDAT sections in compiler_rt that the MSVC linker
rejects (LNK1143), and uses GNU conventions like ___chkstk_ms that
are unavailable in the MSVC CRT.

Default to the MSVC ABI when no explicit ABI is requested, following
the same pattern as the existing macOS target override. This ensures
compiler_rt produces valid COFF and the generated code uses
MSVC-compatible symbols. Users can still explicitly request the GNU
ABI via -Dtarget.

Also disable bundling ubsan_rt on Windows (its /exclude-symbols
directives are MSVC-incompatible) and add ntdll and kernel32 as
transitive link dependencies for the static library.
This commit is contained in:
Mitchell Hashimoto
2026-03-23 11:41:45 -07:00
parent 01401ef675
commit 1eed35dddc
2 changed files with 13 additions and 5 deletions

View File

@@ -83,6 +83,19 @@ pub fn init(b: *std.Build, appVersion: []const u8) !Config {
result = genericMacOSTarget(b, result.query.cpu_arch);
}
// On Windows, default to the MSVC ABI so that produced COFF
// objects (including compiler_rt) are compatible with the MSVC
// linker. Zig defaults to the GNU ABI which produces objects
// with invalid COMDAT sections that MSVC rejects (LNK1143).
// Only override when no explicit ABI was requested.
if (result.result.os.tag == .windows and
result.query.abi == null)
{
var query = result.query;
query.abi = .msvc;
result = b.resolveTargetQuery(query);
}
// If we have no minimum OS version, we set the default based on
// our tag. Not all tags have a minimum so this may be null.
if (result.query.os_version_min == null) {

View File

@@ -110,11 +110,6 @@ fn initLib(
// Zig's ubsan emits /exclude-symbols linker directives that
// are incompatible with the MSVC linker (LNK4229).
lib.bundle_ubsan_rt = false;
// The self-hosted backend produces COFF objects with invalid
// COMDAT sections in compiler_rt that the MSVC linker rejects
// (LNK1143). Use the LLVM backend to produce valid objects.
lib.use_llvm = true;
}
if (lib.rootModuleTarget().abi.isAndroid()) {