From 1c861e3c476f2489008c12fc0b75af72c1b8484d Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 22 Jul 2026 12:56:55 -0700 Subject: [PATCH 1/2] pkg/apple-sdk: support Xcode 27 SDK headers Xcode 27's math.h uses the __need_infinity_nan protocol provided by matching Clang resource headers. Zig 0.16's bundled float.h predates that protocol, causing the bundled libc++ compilation to fail. Overlay the SDK math.h through the Apple SDK libc include path and provide the missing infinity and NaN definitions. The compatibility header can be removed once Zig's bundled Clang headers support the protocol. --- pkg/apple-sdk/build.zig | 16 +++++++++++++++- pkg/apple-sdk/include/math.h | 21 +++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 pkg/apple-sdk/include/math.h diff --git a/pkg/apple-sdk/build.zig b/pkg/apple-sdk/build.zig index 491e23ecf..770b36531 100644 --- a/pkg/apple-sdk/build.zig +++ b/pkg/apple-sdk/build.zig @@ -49,7 +49,7 @@ pub fn pathsForTarget(b: *std.Build, target: std.Target) !Cache.Value { // Detect our SDK using the "findNative" Zig stdlib function. // This is really important because it forces using `xcrun` to // find the SDK path. - const libc = std.zig.LibCInstallation.findNative( + var libc = std.zig.LibCInstallation.findNative( b.allocator, b.graph.io, .{ @@ -59,6 +59,20 @@ pub fn pathsForTarget(b: *std.Build, target: std.Target) !Cache.Value { }, ) catch break :darwin; + // Xcode 27's math.h requests infinity and NaN definitions from + // Clang's float.h using the __need_infinity_nan protocol. Zig + // 0.16's bundled Clang resource headers predate that protocol, so + // compiling Zig's bundled libc++ against the new SDK fails. + // + // Put our compatibility include directory between Zig's resource + // headers and the selected SDK headers. Its math.h forwards to the + // SDK with #include_next, then supplies the definitions missing + // from Zig's float.h. This can be removed once Zig's bundled Clang + // headers implement __need_infinity_nan. + libc.include_dir = b.dependency("apple_sdk", .{}) + .path("include") + .getPath(b); + // Render the file compatible with the `--libc` Zig flag. var stream: std.Io.Writer.Allocating = .init(b.allocator); defer stream.deinit(); diff --git a/pkg/apple-sdk/include/math.h b/pkg/apple-sdk/include/math.h new file mode 100644 index 000000000..507c3c707 --- /dev/null +++ b/pkg/apple-sdk/include/math.h @@ -0,0 +1,21 @@ +#ifndef GHOSTTY_APPLE_SDK_MATH_H +#define GHOSTTY_APPLE_SDK_MATH_H + +// Resume the header search after this compatibility directory so we include +// the selected Xcode SDK's math.h. A regular #include would find this +// wrapper again and loop forever. This is a Clang extension but Zig uses +// Clang so we good. +#include_next + +// Xcode 27's math.h expects Clang's float.h to define these when requested +// with __need_infinity_nan. Zig 0.16's bundled float.h predates that protocol; +// remove these fallbacks once Zig's bundled Clang headers implement it. +#ifndef INFINITY +#define INFINITY (__builtin_inff()) +#endif + +#ifndef NAN +#define NAN (__builtin_nanf("")) +#endif + +#endif From d97a5742423551e8847f2c81f6c10feeb6f5a66e Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 22 Jul 2026 13:04:30 -0700 Subject: [PATCH 2/2] ci: test with Xcode 27 --- .github/workflows/test.yml | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3df8e0a5b..26e597ec4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -102,6 +102,7 @@ jobs: - build-nix # - build-nix-macos - build-macos + - build-macos-xcode-27 - build-macos-freetype - build-snap - test @@ -1109,6 +1110,46 @@ jobs: COMPILATION_CACHE_CAS_PATH=/Users/runner/Library/Developer/Xcode/DerivedData/CompilationCache.noindex \ COMPILATION_CACHE_KEEP_CAS_DIRECTORY=YES + build-macos-xcode-27: + runs-on: namespace-profile-ghostty-macos-tahoe + needs: test + env: + ZIG_LOCAL_CACHE_DIR: /Users/runner/zig/local-cache + ZIG_GLOBAL_CACHE_DIR: /Users/runner/zig/global-cache + steps: + - name: Checkout code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: Setup Cache + uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1 + with: + cache: | + xcode + path: | + /Users/runner/zig + + # TODO(tahoe): https://github.com/NixOS/nix/issues/13342 + - uses: DeterminateSystems/nix-installer-action@main + with: + determinate: true + - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + with: + name: ghostty + authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" + + - name: Xcode Select + run: sudo xcode-select -s /Applications/Xcode_27.app + + - name: Xcode Version + run: xcodebuild -version + + - name: get the Zig deps + id: deps + run: nix build -L .#deps && echo "deps=$(readlink ./result)" >> $GITHUB_OUTPUT + + - name: Build with Xcode 27 + run: nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Demit-macos-app=false + build-macos-freetype: runs-on: namespace-profile-ghostty-macos-tahoe needs: test