main
build.zig
Eric Bower
·
2026-07-27
1const std = @import("std");
2const build_zig_zon = @import("build.zig.zon");
3
4const linux_targets: []const std.Target.Query = &.{
5 .{ .cpu_arch = .x86_64, .os_tag = .linux, .abi = .musl },
6 .{ .cpu_arch = .aarch64, .os_tag = .linux, .abi = .musl },
7};
8
9const macos_targets: []const std.Target.Query = &.{
10 .{ .cpu_arch = .x86_64, .os_tag = .macos },
11 .{ .cpu_arch = .aarch64, .os_tag = .macos },
12};
13
14pub fn build(b: *std.Build) void {
15 const target = b.standardTargetOptions(.{});
16 // const is_macos = target.result.os.tag == .macos;
17 const optimize = b.standardOptimizeOption(.{});
18 const version = b.option([]const u8, "version", "Version string for release") orelse
19 @as([]const u8, build_zig_zon.version);
20
21 const options = b.addOptions();
22 options.addOption([]const u8, "version", version);
23 const ghostty_ver = build_zig_zon.dependencies.ghostty.hash;
24 options.addOption([]const u8, "ghostty_version", ghostty_ver);
25
26 const exe_mod = b.createModule(.{
27 .root_source_file = b.path("src/main.zig"),
28 .target = target,
29 .optimize = optimize,
30 .link_libc = true,
31 });
32 exe_mod.addOptions("build_options", options);
33
34 const dep = b.dependency("ghostty", .{
35 .target = target,
36 .optimize = optimize,
37 .@"emit-lib-vt" = true,
38 // Not redundant: in lib-vt mode emit-xcframework defaults to "xcodebuild
39 // on PATH" (true even via the CLT stub), which pulls in the iOS SDK at
40 // configure time and breaks builds without full Xcode.
41 .@"emit-xcframework" = false,
42 .@"emit-macos-app" = false,
43 });
44 exe_mod.addImport(
45 "ghostty-vt",
46 dep.module("ghostty-vt"),
47 );
48
49 // Run
50 {
51 const run_step = b.step("run", "Run the app");
52 const exe = b.addExecutable(.{
53 .name = "zmx",
54 // .use_llvm = true,
55 // .use_lld = !is_macos,
56 .root_module = exe_mod,
57 });
58
59 b.installArtifact(exe);
60 const run_cmd = b.addRunArtifact(exe);
61 run_cmd.step.dependOn(b.getInstallStep());
62 if (b.args) |args| run_cmd.addArgs(args);
63 run_step.dependOn(&run_cmd.step);
64 }
65
66 // Test
67 {
68 const test_step = b.step("test", "Run unit tests");
69 const test_module = b.addModule("test", .{
70 .root_source_file = b.path("src/test.zig"),
71 .target = target,
72 .optimize = optimize,
73 .link_libc = true,
74 });
75 const test_dep = b.dependency("ghostty", .{
76 .target = target,
77 .optimize = optimize,
78 .@"emit-lib-vt" = true,
79 .@"emit-xcframework" = false,
80 .@"emit-macos-app" = false,
81 });
82 test_module.addImport(
83 "ghostty-vt",
84 test_dep.module("ghostty-vt"),
85 );
86 const exe_unit_tests = b.addTest(.{
87 .root_module = test_module,
88 // .use_llvm = true,
89 // .use_lld = !is_macos,
90 });
91
92 const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
93 test_step.dependOn(&run_exe_unit_tests.step);
94 }
95
96 // Check for LSP integration
97 {
98 const check = b.step("check", "Check if zmx compiles");
99 const exe_check = b.addExecutable(.{
100 .name = "zmx",
101 // .use_llvm = true,
102 // .use_lld = !is_macos,
103 .root_module = exe_mod,
104 });
105
106 // Finally we add the "check" step which will be detected
107 // by ZLS and automatically enable Build-On-Save.
108 // If you copy this into your `build.zig`, make sure to rename 'foo'
109 check.dependOn(&exe_check.step);
110 }
111
112 // Release step - cross-compile to all targets from any host
113 {
114 const release_step = b.step(
115 "release",
116 "Build release binaries for all platforms",
117 );
118 const release_targets = linux_targets ++ macos_targets;
119 for (release_targets) |release_target| {
120 const resolved = b.resolveTargetQuery(release_target);
121 const release_mod = b.createModule(.{
122 .root_source_file = b.path("src/main.zig"),
123 .target = resolved,
124 .optimize = .ReleaseSafe,
125 .link_libc = true,
126 });
127 release_mod.addOptions("build_options", options);
128
129 if (b.lazyDependency("ghostty", .{
130 .target = resolved,
131 .optimize = .ReleaseSafe,
132 .@"emit-lib-vt" = true,
133 .@"emit-xcframework" = false,
134 .@"emit-macos-app" = false,
135 })) |release_dep| {
136 release_mod.addImport("ghostty-vt", release_dep.module("ghostty-vt"));
137 }
138
139 // const is_local_macos = resolved.result.os.tag == .macos;
140 const release_exe = b.addExecutable(.{
141 .name = "zmx",
142 // .use_llvm = true,
143 // .use_lld = !is_local_macos,
144 .root_module = release_mod,
145 });
146
147 const os_name = @tagName(release_target.os_tag orelse .linux);
148 const arch_name = @tagName(release_target.cpu_arch orelse .x86_64);
149 const tarball_name = b.fmt("zmx-{s}-{s}-{s}.tar.gz", .{ version, os_name, arch_name });
150
151 const tar = b.addSystemCommand(&.{ "tar", "-czf" });
152
153 const tarball = tar.addOutputFileArg(tarball_name);
154 tar.addArg("-C");
155 tar.addDirectoryArg(release_exe.getEmittedBinDirectory());
156 tar.addArg("zmx");
157
158 const shasum = b.addSystemCommand(&.{"sha256sum"});
159 shasum.addFileArg(tarball);
160 const shasum_output = shasum.captureStdOut(.{});
161
162 const install_tar = b.addInstallFile(tarball, b.fmt("dist/{s}", .{tarball_name}));
163 const install_sha = b.addInstallFile(
164 shasum_output,
165 b.fmt("dist/{s}.sha256", .{tarball_name}),
166 );
167 release_step.dependOn(&install_tar.step);
168 release_step.dependOn(&install_sha.step);
169 }
170 }
171}