diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-04-04 19:22:04 +0300 |
|---|---|---|
| committer | Can Celik <ogulcancelik@gmail.com> | 2026-04-05 01:23:06 +0300 |
| commit | 41dd733ca7123c9ac4bfc6c781697a660e95b052 (patch) | |
| tree | 3fc91815ca139ef2e0b281bba0abda4ef15175f4 /vendor/libghostty-vt/src/build/GhosttyXcodebuild.zig | |
| parent | 55c138263e190a1e79d4b997bfb9397306c0ec1f (diff) | |
feat: finish ghostty pane backend integration
Diffstat (limited to 'vendor/libghostty-vt/src/build/GhosttyXcodebuild.zig')
| -rw-r--r-- | vendor/libghostty-vt/src/build/GhosttyXcodebuild.zig | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/src/build/GhosttyXcodebuild.zig b/vendor/libghostty-vt/src/build/GhosttyXcodebuild.zig new file mode 100644 index 00000000..81af994c --- /dev/null +++ b/vendor/libghostty-vt/src/build/GhosttyXcodebuild.zig @@ -0,0 +1,203 @@ +const Ghostty = @This(); + +const std = @import("std"); +const builtin = @import("builtin"); +const RunStep = std.Build.Step.Run; +const Config = @import("Config.zig"); +const Docs = @import("GhosttyDocs.zig"); +const I18n = @import("GhosttyI18n.zig"); +const Resources = @import("GhosttyResources.zig"); +const XCFramework = @import("GhosttyXCFramework.zig"); + +build: *std.Build.Step.Run, +open: *std.Build.Step.Run, +copy: *std.Build.Step.Run, +xctest: *std.Build.Step.Run, + +pub const Deps = struct { + xcframework: *const XCFramework, + docs: *const Docs, + i18n: ?*const I18n, + resources: *const Resources, +}; + +pub fn init( + b: *std.Build, + config: *const Config, + deps: Deps, +) !Ghostty { + const xc_config = switch (config.optimize) { + .Debug => "Debug", + .ReleaseSafe, + .ReleaseSmall, + .ReleaseFast, + => "ReleaseLocal", + }; + + const xc_arch: ?[]const u8 = switch (deps.xcframework.target) { + // Universal is our default target, so we don't have to + // add anything. + .universal => null, + + // Native we need to override the architecture in the Xcode + // project with the -arch flag. + .native => switch (builtin.cpu.arch) { + .aarch64 => "arm64", + .x86_64 => "x86_64", + else => @panic("unsupported macOS arch"), + }, + }; + + const env = try std.process.getEnvMap(b.allocator); + const app_path = b.fmt("macos/build/{s}/Ghostty.app", .{xc_config}); + + // Our step to build the Ghostty macOS app. + const build = build: { + // External environment variables can mess up xcodebuild, so + // we create a new empty environment. + const env_map = try b.allocator.create(std.process.EnvMap); + env_map.* = .init(b.allocator); + if (env.get("PATH")) |v| try env_map.put("PATH", v); + + const step = RunStep.create(b, "xcodebuild"); + step.has_side_effects = true; + step.cwd = b.path("macos"); + step.env_map = env_map; + step.addArgs(&.{ + "xcodebuild", + "-target", + "Ghostty", + "-configuration", + xc_config, + }); + + // If we have a specific architecture, we need to pass it + // to xcodebuild. + if (xc_arch) |arch| step.addArgs(&.{ "-arch", arch }); + + // We need the xcframework + deps.xcframework.addStepDependencies(&step.step); + + // We also need all these resources because the xcode project + // references them via symlinks. + deps.resources.addStepDependencies(&step.step); + if (deps.i18n) |v| v.addStepDependencies(&step.step); + deps.docs.installDummy(&step.step); + + // Expect success + step.expectExitCode(0); + + break :build step; + }; + + const xctest = xctest: { + const env_map = try b.allocator.create(std.process.EnvMap); + env_map.* = .init(b.allocator); + if (env.get("PATH")) |v| try env_map.put("PATH", v); + + const step = RunStep.create(b, "xcodebuild test"); + step.has_side_effects = true; + step.cwd = b.path("macos"); + step.env_map = env_map; + step.addArgs(&.{ + "xcodebuild", + "test", + "-scheme", + "Ghostty", + "-skip-testing", + "GhosttyUITests", + }); + if (xc_arch) |arch| step.addArgs(&.{ "-arch", arch }); + + // We need the xcframework + deps.xcframework.addStepDependencies(&step.step); + + // We also need all these resources because the xcode project + // references them via symlinks. + deps.resources.addStepDependencies(&step.step); + if (deps.i18n) |v| v.addStepDependencies(&step.step); + deps.docs.installDummy(&step.step); + + // Expect success + step.expectExitCode(0); + + break :xctest step; + }; + + // Our step to open the resulting Ghostty app. + const open = open: { + const disable_save_state = RunStep.create(b, "disable save state"); + disable_save_state.has_side_effects = true; + disable_save_state.addArgs(&.{ + "/usr/libexec/PlistBuddy", + "-c", + // We'll have to change this to `Set` if we ever put this + // into our Info.plist. + "Add :NSQuitAlwaysKeepsWindows bool false", + b.fmt("{s}/Contents/Info.plist", .{app_path}), + }); + disable_save_state.expectExitCode(0); + disable_save_state.step.dependOn(&build.step); + + const open = RunStep.create(b, "run Ghostty app"); + open.has_side_effects = true; + open.cwd = b.path(""); + open.addArgs(&.{b.fmt( + "{s}/Contents/MacOS/ghostty", + .{app_path}, + )}); + + // Open depends on the app + open.step.dependOn(&build.step); + open.step.dependOn(&disable_save_state.step); + + // This overrides our default behavior and forces logs to show + // up on stderr (in addition to the centralized macOS log). + open.setEnvironmentVariable("GHOSTTY_LOG", "stderr,macos"); + + // Configure how we're launching + open.setEnvironmentVariable("GHOSTTY_MAC_LAUNCH_SOURCE", "zig_run"); + + if (b.args) |args| { + open.addArgs(args); + } + + break :open open; + }; + + // Our step to copy the app bundle to the install path. + // We have to use `cp -R` because there are symlinks in the + // bundle. + const copy = copy: { + const step = RunStep.create(b, "copy app bundle"); + step.addArgs(&.{ "cp", "-R" }); + step.addFileArg(b.path(app_path)); + step.addArg(b.fmt("{s}", .{b.install_path})); + step.step.dependOn(&build.step); + break :copy step; + }; + + return .{ + .build = build, + .open = open, + .copy = copy, + .xctest = xctest, + }; +} + +pub fn install(self: *const Ghostty) void { + const b = self.copy.step.owner; + b.getInstallStep().dependOn(&self.copy.step); +} + +pub fn installXcframework(self: *const Ghostty) void { + const b = self.build.step.owner; + b.getInstallStep().dependOn(&self.build.step); +} + +pub fn addTestStepDependencies( + self: *const Ghostty, + other_step: *std.Build.Step, +) void { + other_step.dependOn(&self.xctest.step); +} |
