summaryrefslogtreecommitdiff
path: root/build.zig
diff options
context:
space:
mode:
Diffstat (limited to 'build.zig')
-rw-r--r--build.zig59
1 files changed, 56 insertions, 3 deletions
diff --git a/build.zig b/build.zig
index feefecdc..8a07cf16 100644
--- a/build.zig
+++ b/build.zig
@@ -2,7 +2,7 @@ const std = @import("std");
const mupdf_build = @import("mupdf.zig");
const snap_build = @import("build/snap.zig");
-pub const Platform = enum { tty, gui, web };
+pub const Platform = enum { tty, gui, web, macos };
/// The ZLS the language backend links, spelled once. It names the commit
/// build.zig.zon pins (0.16.x branch) and is passed BOTH to ZLS's own
@@ -24,7 +24,7 @@ pub fn build(b: *std.Build) void {
.glibc_version = .{ .major = 2, .minor = 38, .patch = 0 },
} });
const requested_optimize = b.standardOptimizeOption(.{});
- const platform = b.option(Platform, "platform", "which shell to build (tty, gui, web)") orelse .tty;
+ const platform = b.option(Platform, "platform", "which shell to build (tty, gui, web, macos)") orelse .tty;
const static = b.option(bool, "static", "statically link") orelse false;
const dump_path = b.option([]const u8, "dump", "dump .zon embedded into the web shell (-Dplatform=web)");
const is_web = platform == .web;
@@ -96,7 +96,13 @@ pub fn build(b: *std.Build) void {
const root_mod = b.createModule(.{
.target = target,
.optimize = optimize,
- .root_source_file = b.path(if (is_web) "src/web.zig" else "src/main.zig"),
+ // The browser and macOS shells are libraries whose host owns main():
+ // each roots at its own flat C ABI instead of src/main.zig.
+ .root_source_file = b.path(switch (platform) {
+ .web => "src/web.zig",
+ .macos => "src/macos.zig",
+ .tty, .gui => "src/main.zig",
+ }),
.link_libc = !is_web,
});
// helix differential harness (test/hxdiff.zig): a second compilation of
@@ -635,6 +641,53 @@ pub fn build(b: *std.Build) void {
run_web_harness.step.dependOn(web_step);
b.step("web-harness", "run the dependency-free JS/WASM DOM harness").dependOn(&run_web_harness.step);
b.getInstallStep().dependOn(web_step);
+ } else if (platform == .macos) {
+ // The native macOS shell is a static library plus a Swift app: Zig
+ // keeps the core, the ptys and every effect; Swift owns AppKit and
+ // draws the cell grid with CoreText. See docs/macos.md.
+ //
+ // The Zig half is ordinary POSIX and builds anywhere, which is what
+ // makes the boundary testable without a Mac — only `macos-app` needs
+ // one. Deliberately NOT here: an xcframework, lipo, an Xcode project
+ // and codesigning. Those exist to ship a signed universal bundle, and
+ // this is a dev build; ghostty's src/build/GhosttyXCFramework.zig is
+ // the map when distribution matters.
+ const header = b.addTranslateC(.{
+ .root_source_file = b.path("src/macos/pardes.h"),
+ .target = target,
+ .optimize = optimize,
+ });
+ // The header is hand-written, so only a test keeps it in step with the
+ // Zig side. Importing the translated header makes it a checkable
+ // artifact — see the ABI guard at the bottom of src/macos.zig.
+ root_mod.addImport("pardes.h", header.createModule());
+
+ const lib = b.addLibrary(.{
+ .name = "pardes",
+ .linkage = .static,
+ .root_module = root_mod,
+ });
+ // Swift links this archive directly, so the runtime support Zig would
+ // otherwise expect from a Zig-linked executable has to travel inside
+ // it or every build ends in undefined symbols at the swiftc link.
+ lib.bundle_compiler_rt = true;
+ lib.bundle_ubsan_rt = true;
+ b.installArtifact(lib);
+ b.installFile("src/macos/pardes.h", "include/pardes.h");
+
+ const app = b.addSystemCommand(&.{"src/macos/build-app.sh"});
+ app.addArg(b.getInstallPath(.prefix, ""));
+ app.has_side_effects = true; // writes a bundle outside the cache
+ app.step.dependOn(b.getInstallStep());
+ b.step("macos-app", "assemble zig-out/pardes.app (needs macOS + swiftc)").dependOn(&app.step);
+
+ // Same step name the other native platforms use, because in this
+ // configuration theirs is not declared: the ABI guard and the core's
+ // own inline tests are what `-Dplatform=macos` has to keep green.
+ const unit_step = b.step("unit-test", "run the C-ABI guard and the core unit tests");
+ unit_step.dependOn(&b.addRunArtifact(b.addTest(.{ .root_module = root_mod })).step);
+ unit_step.dependOn(&b.addRunArtifact(b.addTest(.{ .root_module = hx_core_mod })).step);
+ web_step.dependOn(&b.addFail("web needs -Dplatform=web -Dtarget=wasm32-freestanding -Ddump=<dump.zon>").step);
} else {
// binary name: the native-shaped linux-x86_64 tty build stays `pardes`
// (the snap suite and e2e harness drive zig-out/bin/pardes); the gui