mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00

`zig build run` on macOS now builds the app bundle via the `xcodebuild` CLI and runs it. The experience for running the app is now very similar to Linux or the prior GLFW build, where the app runs, blocks the zig command, and logs to the terminal. `xcodebuild` has its own build cache system that we can't really hook into so it runs on every `zig build run` command, but it does cache and I find its actually relatively fast so I think this is a good replacement for the glfw-based system.
160 lines
5.5 KiB
Zig
160 lines
5.5 KiB
Zig
const std = @import("std");
|
|
const assert = std.debug.assert;
|
|
const builtin = @import("builtin");
|
|
const buildpkg = @import("src/build/main.zig");
|
|
|
|
comptime {
|
|
buildpkg.requireZig("0.14.0");
|
|
}
|
|
|
|
pub fn build(b: *std.Build) !void {
|
|
const config = try buildpkg.Config.init(b);
|
|
|
|
// Ghostty resources like terminfo, shell integration, themes, etc.
|
|
const resources = try buildpkg.GhosttyResources.init(b, &config);
|
|
const i18n = try buildpkg.GhosttyI18n.init(b, &config);
|
|
|
|
// Ghostty dependencies used by many artifacts.
|
|
const deps = try buildpkg.SharedDeps.init(b, &config);
|
|
if (config.emit_helpgen) deps.help_strings.install();
|
|
|
|
// Ghostty executable, the actual runnable Ghostty program.
|
|
const exe = try buildpkg.GhosttyExe.init(b, &config, &deps);
|
|
|
|
// Ghostty docs
|
|
const docs = try buildpkg.GhosttyDocs.init(b, &deps);
|
|
if (config.emit_docs) docs.install();
|
|
|
|
// Ghostty webdata
|
|
const webdata = try buildpkg.GhosttyWebdata.init(b, &deps);
|
|
if (config.emit_webdata) webdata.install();
|
|
|
|
// Ghostty bench tools
|
|
const bench = try buildpkg.GhosttyBench.init(b, &deps);
|
|
if (config.emit_bench) bench.install();
|
|
|
|
// Ghostty dist tarball
|
|
const dist = try buildpkg.GhosttyDist.init(b, &config);
|
|
{
|
|
const step = b.step("dist", "Build the dist tarball");
|
|
step.dependOn(dist.install_step);
|
|
const check_step = b.step("distcheck", "Install and validate the dist tarball");
|
|
check_step.dependOn(dist.check_step);
|
|
check_step.dependOn(dist.install_step);
|
|
}
|
|
|
|
// If we're not building libghostty, then install the exe and resources.
|
|
if (config.app_runtime != .none) {
|
|
exe.install();
|
|
resources.install();
|
|
i18n.install();
|
|
|
|
// Run runs the Ghostty exe. We only do this if we are building
|
|
// an apprt.
|
|
{
|
|
const run_cmd = b.addRunArtifact(exe.exe);
|
|
if (b.args) |args| run_cmd.addArgs(args);
|
|
|
|
// Set the proper resources dir so things like shell integration
|
|
// work correctly. If we're running `zig build run` in Ghostty,
|
|
// this also ensures it overwrites the release one with our debug
|
|
// build.
|
|
run_cmd.setEnvironmentVariable(
|
|
"GHOSTTY_RESOURCES_DIR",
|
|
b.getInstallPath(.prefix, "share/ghostty"),
|
|
);
|
|
|
|
const run_step = b.step("run", "Run the app");
|
|
run_step.dependOn(&run_cmd.step);
|
|
}
|
|
}
|
|
|
|
// Libghostty
|
|
//
|
|
// Note: libghostty is not stable for general purpose use. It is used
|
|
// heavily by Ghostty on macOS but it isn't built to be reusable yet.
|
|
// As such, these build steps are lacking. For example, the Darwin
|
|
// build only produces an xcframework.
|
|
if (config.app_runtime == .none) none: {
|
|
if (!config.target.result.os.tag.isDarwin()) {
|
|
const libghostty_shared = try buildpkg.GhosttyLib.initShared(
|
|
b,
|
|
&deps,
|
|
);
|
|
const libghostty_static = try buildpkg.GhosttyLib.initStatic(
|
|
b,
|
|
&deps,
|
|
);
|
|
libghostty_shared.installHeader(); // Only need one header
|
|
libghostty_shared.install("libghostty.so");
|
|
libghostty_static.install("libghostty.a");
|
|
break :none;
|
|
}
|
|
|
|
assert(config.target.result.os.tag.isDarwin());
|
|
if (!config.emit_xcframework) break :none;
|
|
|
|
// Build the xcframework
|
|
const xcframework = try buildpkg.GhosttyXCFramework.init(b, &deps);
|
|
xcframework.install();
|
|
|
|
// The xcframework build always installs resources because our
|
|
// macOS xcode project contains references to them.
|
|
resources.install();
|
|
i18n.install();
|
|
|
|
// If we aren't emitting docs we need to emit a placeholder so
|
|
// our macOS xcodeproject builds.
|
|
if (!config.emit_docs) {
|
|
var wf = b.addWriteFiles();
|
|
const path = "share/man/.placeholder";
|
|
const placeholder = wf.add(path, "emit-docs not true so no man pages");
|
|
b.getInstallStep().dependOn(&b.addInstallFile(placeholder, path).step);
|
|
}
|
|
|
|
// Build our macOS app
|
|
const app = try buildpkg.GhosttyXcodebuild.init(
|
|
b,
|
|
&config,
|
|
&xcframework,
|
|
);
|
|
|
|
// Add a run command that opens our mac app.
|
|
const run_step = b.step("run", "Run the app");
|
|
run_step.dependOn(&app.open.step);
|
|
}
|
|
|
|
// Tests
|
|
{
|
|
const test_step = b.step("test", "Run all tests");
|
|
const test_filter = b.option([]const u8, "test-filter", "Filter for test");
|
|
|
|
const test_exe = b.addTest(.{
|
|
.name = "ghostty-test",
|
|
.filters = if (test_filter) |v| &.{v} else &.{},
|
|
.root_module = b.createModule(.{
|
|
.root_source_file = b.path("src/main.zig"),
|
|
.target = config.target,
|
|
.optimize = .Debug,
|
|
.strip = false,
|
|
.omit_frame_pointer = false,
|
|
.unwind_tables = .sync,
|
|
}),
|
|
});
|
|
|
|
{
|
|
if (config.emit_test_exe) b.installArtifact(test_exe);
|
|
_ = try deps.add(test_exe);
|
|
const test_run = b.addRunArtifact(test_exe);
|
|
test_step.dependOn(&test_run.step);
|
|
}
|
|
}
|
|
|
|
// update-translations does what it sounds like and updates the "pot"
|
|
// files. These should be committed to the repo.
|
|
{
|
|
const step = b.step("update-translations", "Update translation files");
|
|
step.dependOn(i18n.update_step);
|
|
}
|
|
}
|