build: fix static libghostty-vt linking on Windows (#13452)

This PR fixes static linking for libghostty-vt on Windows by propagating
a couple of missing dependencies (discovered while running Neovim's Zig
build, see [this CI
run](https://github.com/neovim/neovim/actions/runs/30130848061/job/89604799965?pr=39773)).
This commit is contained in:
Mitchell Hashimoto
2026-07-26 15:40:29 -07:00
committed by GitHub
7 changed files with 55 additions and 4 deletions

View File

@@ -742,6 +742,10 @@ jobs:
- name: Build libghostty-vt
run: zig build -Demit-lib-vt
- name: Test static linking
working-directory: example/c-vt-static
run: zig build
build-libghostty-windows-gnu:
runs-on: namespace-profile-ghostty-windows
timeout-minutes: 45

View File

@@ -14,6 +14,7 @@ pub fn build(b: *std.Build) void {
.root = b.path("src"),
.files = &.{"main.c"},
});
exe_mod.addCMacro("GHOSTTY_STATIC", "");
// You'll want to use a lazy dependency here so that ghostty is only
// downloaded if you actually need it.

View File

@@ -99,6 +99,13 @@ pub fn build(b: *std.Build) !void {
"-fmath-errno",
"-fno-exceptions",
});
} else if (target.result.abi == .msvc) {
try flags.appendSlice(b.allocator, &.{
// -fno-autolink also drops UCRT's /alternatename fallback.
"-D_Avx2WmemEnabledWeakValue=_Avx2WmemEnabled",
"-fno-autolink",
"-fno-stack-protector",
});
}
lib.root_module.addCSourceFiles(.{ .flags = flags.items, .files = &.{

View File

@@ -50,10 +50,16 @@ pub fn build(b: *std.Build) !void {
if (no_libcxx) {
try flags.append(b.allocator, "-DSIMDUTF_NO_LIBCXX");
if (target.result.abi != .msvc) {
// Clang/GCC-only flags; MSVC doesn't accept these.
try flags.append(b.allocator, "-fno-exceptions");
try flags.append(b.allocator, "-fno-rtti");
try flags.append(b.allocator, "-fno-exceptions");
try flags.append(b.allocator, "-fno-rtti");
if (target.result.abi == .msvc) {
try flags.appendSlice(b.allocator, &.{
"-D_USE_STD_VECTOR_ALGORITHMS=0",
// -fno-autolink also drops UCRT's /alternatename fallback.
"-D_Avx2WmemEnabledWeakValue=_Avx2WmemEnabled",
"-fno-autolink",
"-fno-stack-protector",
});
}
lib.root_module.addCMacro("SIMDUTF_NO_LIBCXX", "1");

View File

@@ -247,6 +247,19 @@ fn initLib(
// Zig's ubsan emits /exclude-symbols linker directives that
// are incompatible with the MSVC linker (LNK4229).
lib.bundle_ubsan_rt = false;
if (kind == .static) {
if (target.result.abi == .msvc) {
// Zig's compiler runtime doesn't provide MSVC's security
// cookie symbols when libc is linked. Disable stack-protector
// generation so static consumers don't need BufferOverflowU.
lib.root_module.stack_protector = false;
}
// The Zig standard library uses NT and kernel32 symbols.
lib.root_module.linkSystemLibrary("ntdll", .{});
lib.root_module.linkSystemLibrary("kernel32", .{});
}
}
if (lib.rootModuleTarget().abi.isAndroid()) {

View File

@@ -991,6 +991,11 @@ pub fn addSimd(
"-fno-sanitize=undefined",
"-fno-sanitize-trap=undefined",
});
if (target.result.abi == .msvc) try flags.appendSlice(b.allocator, &.{
// -fno-autolink also drops UCRT's /alternatename fallback.
"-D_Avx2WmemEnabledWeakValue=_Avx2WmemEnabled",
"-fno-autolink",
});
m.addCSourceFiles(.{
.files = &.{

View File

@@ -141,10 +141,25 @@ pub const unicode = struct {
pub const graphemeWidth = unicode_pkg.graphemeWidth;
};
/// Used for MSVC builds (see below)
var msvc_fltused: c_int = 1;
comptime {
// If we're building the C library (vs. the Zig module) then
// we want to reference the C API so that it gets exported.
if (@import("root") == lib) {
// MSVC requires this marker whenever floating-point code is present.
// Zig's compiler_rt only provides it when libc is not linked.
if (builtin.os.tag == .windows and
builtin.abi == .msvc and
builtin.link_mode == .static)
{
@export(
&msvc_fltused,
.{ .name = "_fltused" },
);
}
// Force-reference our memset override so its export is
// emitted. This must stay inside the root guard so that
// downstream Zig module consumers don't get the override