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