build: skip linkLibCpp on MSVC targets

Zig's bundled libc++/libc++abi conflicts with the MSVC C++ runtime
headers (vcruntime_typeinfo.h, vcruntime_exception.h, etc.) when
targeting native-native-msvc. This caused compilation failures in
the SIMD C++ code due to -nostdinc++ suppressing MSVC headers and
libc++ types clashing with MSVC runtime types.

Skip linkLibCpp() for MSVC targets across all packages (highway,
simdutf, utfcpp) and the main build (SharedDeps, GhosttyZig) since
MSVC provides its own C++ standard library natively. Also add
missing <iterator> and <cstddef> includes that were previously
pulled in transitively through libc++ headers but are not
guaranteed by MSVC's headers.
This commit is contained in:
Mitchell Hashimoto
2026-03-23 11:56:31 -07:00
parent 1eed35dddc
commit afa8f059e5
7 changed files with 27 additions and 6 deletions

View File

@@ -20,7 +20,11 @@ pub fn build(b: *std.Build) !void {
}),
.linkage = .static,
});
lib.linkLibCpp();
// On MSVC, the C++ standard library is provided by the MSVC runtime
// and linking Zig's bundled libc++ would conflict with it.
if (target.result.abi != .msvc) {
lib.linkLibCpp();
}
if (upstream_) |upstream| {
lib.addIncludePath(upstream.path(""));
module.addIncludePath(upstream.path(""));

View File

@@ -12,7 +12,11 @@ pub fn build(b: *std.Build) !void {
}),
.linkage = .static,
});
lib.linkLibCpp();
// On MSVC, the C++ standard library is provided by the MSVC runtime
// and linking Zig's bundled libc++ would conflict with it.
if (target.result.abi != .msvc) {
lib.linkLibCpp();
}
lib.addIncludePath(b.path("vendor"));
if (target.result.os.tag.isDarwin()) {

View File

@@ -12,7 +12,11 @@ pub fn build(b: *std.Build) !void {
}),
.linkage = .static,
});
lib.linkLibCpp();
// On MSVC, the C++ standard library is provided by the MSVC runtime
// and linking Zig's bundled libc++ would conflict with it.
if (target.result.abi != .msvc) {
lib.linkLibCpp();
}
if (target.result.os.tag.isDarwin()) {
const apple_sdk = @import("apple_sdk");

View File

@@ -64,8 +64,10 @@ fn initVt(
.optimize = cfg.optimize,
// SIMD require libc/libcpp (both) but otherwise we don't care.
// On MSVC, the C++ standard library is provided by the MSVC runtime
// and linking libc++ would conflict with it.
.link_libc = if (cfg.simd) true else null,
.link_libcpp = if (cfg.simd) true else null,
.link_libcpp = if (cfg.simd and cfg.target.result.abi != .msvc) true else null,
});
vt.addOptions("build_options", general_options);
vt_options.add(b, vt);

View File

@@ -399,8 +399,12 @@ pub fn add(
step.addIncludePath(b.path("src/apprt/gtk"));
}
// libcpp is required for various dependencies
step.linkLibCpp();
// libcpp is required for various dependencies. On MSVC, the C++
// standard library is provided by the MSVC runtime and linking
// libc++ would conflict with it.
if (step.rootModuleTarget().abi != .msvc) {
step.linkLibCpp();
}
// We always require the system SDK so that our system headers are available.
// This makes things like `os/log.h` available for cross-compiling.

View File

@@ -6,6 +6,7 @@
#include <hwy/print-inl.h>
#include <cassert>
#include <iterator>
HWY_BEFORE_NAMESPACE();
namespace ghostty {

View File

@@ -6,6 +6,8 @@
#endif
#include <hwy/highway.h>
#include <cstddef>
#include <optional>
HWY_BEFORE_NAMESPACE();