build: fix ghostty.dll linking on Windows MSVC

linkLibC() provides msvcrt.lib for DLL targets but doesn't include the
companion CRT bootstrap libraries. The DLL startup code in msvcrt.lib
calls __vcrt_initialize and __acrt_initialize, which live in the static
CRT libraries (libvcruntime.lib, libucrt.lib).

Detect the Windows 10 SDK installation via std.zig.WindowsSdk to add
the UCRT library path, which Zig's default search paths don't include
(they add um\x64 but not ucrt\x64).

This is a workaround for a Zig gap (partially addressed in closed
issues 5748, 5842 on ziglang/zig). Only affects initShared (DLL),
not initStatic.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alessandro De Blasis
2026-03-25 16:35:19 +01:00
committed by Mitchell Hashimoto
parent 5ae7068a41
commit 335d7f01db

View File

@@ -94,6 +94,44 @@ pub fn initShared(
});
_ = try deps.add(lib);
// On Windows with MSVC, building a DLL requires the full CRT library
// chain. linkLibC() (called via deps.add) provides msvcrt.lib, but
// that references symbols in vcruntime.lib and ucrt.lib. Zig's library
// search paths include the MSVC lib dir and the Windows SDK 'um' dir,
// but not the SDK 'ucrt' dir where ucrt.lib lives.
if (deps.config.target.result.os.tag == .windows and
deps.config.target.result.abi == .msvc)
{
// The CRT initialization code in msvcrt.lib calls __vcrt_initialize
// and __acrt_initialize, which are in the static CRT libraries.
lib.linkSystemLibrary("libvcruntime");
// ucrt.lib is in the Windows SDK 'ucrt' dir. Detect the SDK
// installation and add the UCRT library path.
const arch = deps.config.target.result.cpu.arch;
const sdk = std.zig.WindowsSdk.find(b.graph.arena, arch) catch null;
if (sdk) |s| {
if (s.windows10sdk) |w10| {
const arch_str: []const u8 = switch (arch) {
.x86_64 => "x64",
.x86 => "x86",
.aarch64 => "arm64",
else => "x64",
};
const ucrt_lib_path = std.fmt.allocPrint(
b.graph.arena,
"{s}\\Lib\\{s}\\ucrt\\{s}",
.{ w10.path, w10.version, arch_str },
) catch null;
if (ucrt_lib_path) |path| {
lib.addLibraryPath(.{ .cwd_relative = path });
}
}
}
lib.linkSystemLibrary("libucrt");
}
// Get our debug symbols
const dsymutil: ?std.Build.LazyPath = dsymutil: {
if (!deps.config.target.result.os.tag.isDarwin()) {