Commit 5389d30
Eric Bower
·
2026-04-26 22:48:18 -0400 EDT
parent b79c8c7
feat: cross-compile from linux to mac Latest version of libghostty now supports cross-compiling without needing Apple sdk tools.
3 files changed,
+32,
-36
+17,
-21
| ... | ... | @@ -36,15 +36,14 @@ pub fn build(b: *std.Build) void { | |
| 36 | 36 | }); | |
| 37 | 37 | exe_mod.addOptions("build_options", options); | |
| 38 | 38 | ||
| 39 | - | if (b.lazyDependency("ghostty", .{ | |
| 39 | + | const dep = b.dependency("ghostty", .{ | |
| 40 | 40 | .target = target, | |
| 41 | 41 | .optimize = optimize, | |
| 42 | - | })) |dep| { | |
| 43 | - | exe_mod.addImport( | |
| 44 | - | "ghostty-vt", | |
| 45 | - | dep.module("ghostty-vt"), | |
| 46 | - | ); | |
| 47 | - | } | |
| 42 | + | }); | |
| 43 | + | exe_mod.addImport( | |
| 44 | + | "ghostty-vt", | |
| 45 | + | dep.module("ghostty-vt"), | |
| 46 | + | ); | |
| 48 | 47 | ||
| 49 | 48 | // Run | |
| 50 | 49 | { |
| ... | ... | @@ -69,15 +68,14 @@ pub fn build(b: *std.Build) void { | |
| 69 | 68 | .target = target, | |
| 70 | 69 | .optimize = optimize, | |
| 71 | 70 | }); | |
| 72 | - | if (b.lazyDependency("ghostty", .{ | |
| 71 | + | const test_dep = b.dependency("ghostty", .{ | |
| 73 | 72 | .target = target, | |
| 74 | 73 | .optimize = optimize, | |
| 75 | - | })) |dep| { | |
| 76 | - | test_module.addImport( | |
| 77 | - | "ghostty-vt", | |
| 78 | - | dep.module("ghostty-vt"), | |
| 79 | - | ); | |
| 80 | - | } | |
| 74 | + | }); | |
| 75 | + | test_module.addImport( | |
| 76 | + | "ghostty-vt", | |
| 77 | + | test_dep.module("ghostty-vt"), | |
| 78 | + | ); | |
| 81 | 79 | const exe_unit_tests = b.addTest(.{ | |
| 82 | 80 | .root_module = test_module, | |
| 83 | 81 | }); |
| ... | ... | @@ -108,15 +106,13 @@ pub fn build(b: *std.Build) void { | |
| 108 | 106 | check.dependOn(&exe_check.step); | |
| 109 | 107 | } | |
| 110 | 108 | ||
| 111 | - | // Release step - macOS can cross-compile to Linux, | |
| 112 | - | // but Linux cannot cross-compile to macOS (needs SDK) | |
| 109 | + | // Release step - cross-compile to all targets from any host | |
| 113 | 110 | { | |
| 114 | 111 | const release_step = b.step( | |
| 115 | 112 | "release", | |
| 116 | - | "Build release binaries (macOS builds all, Linux builds Linux only)", | |
| 113 | + | "Build release binaries for all platforms", | |
| 117 | 114 | ); | |
| 118 | - | const native_os = @import("builtin").os.tag; | |
| 119 | - | const release_targets = if (native_os == .macos) linux_targets ++ macos_targets else linux_targets; | |
| 115 | + | const release_targets = linux_targets ++ macos_targets; | |
| 120 | 116 | for (release_targets) |release_target| { | |
| 121 | 117 | const resolved = b.resolveTargetQuery(release_target); | |
| 122 | 118 | const release_mod = b.createModule(.{ |
| ... | ... | @@ -129,8 +125,8 @@ pub fn build(b: *std.Build) void { | |
| 129 | 125 | if (b.lazyDependency("ghostty", .{ | |
| 130 | 126 | .target = resolved, | |
| 131 | 127 | .optimize = .ReleaseSafe, | |
| 132 | - | })) |dep| { | |
| 133 | - | release_mod.addImport("ghostty-vt", dep.module("ghostty-vt")); | |
| 128 | + | })) |release_dep| { | |
| 129 | + | release_mod.addImport("ghostty-vt", release_dep.module("ghostty-vt")); | |
| 134 | 130 | } | |
| 135 | 131 | ||
| 136 | 132 | const release_exe = b.addExecutable(.{ |
+2,
-2
| ... | ... | @@ -1135,7 +1135,7 @@ const Daemon = struct { | |
| 1135 | 1135 | } | |
| 1136 | 1136 | ||
| 1137 | 1137 | pub fn handleOutput(self: *Daemon, payload: []const u8, vt_stream: anytype) !void { | |
| 1138 | - | try vt_stream.nextSlice(payload); | |
| 1138 | + | vt_stream.nextSlice(payload); | |
| 1139 | 1139 | self.has_pty_output = true; | |
| 1140 | 1140 | for (self.clients.items) |client| { | |
| 1141 | 1141 | try ipc.appendMessage(self.alloc, &client.write_buf, .Output, payload); |
| ... | ... | @@ -2417,7 +2417,7 @@ fn daemonLoop(daemon: *Daemon, server_sock_fd: i32, pty_fd: i32) !void { | |
| 2417 | 2417 | break :daemon_loop; | |
| 2418 | 2418 | } else { | |
| 2419 | 2419 | // Feed PTY output to terminal emulator for state tracking | |
| 2420 | - | try vt_stream.nextSlice(buf[0..n]); | |
| 2420 | + | vt_stream.nextSlice(buf[0..n]); | |
| 2421 | 2421 | daemon.has_pty_output = true; | |
| 2422 | 2422 | ||
| 2423 | 2423 | // When no real terminal client has attached yet, respond to |
+13,
-13
| ... | ... | @@ -980,9 +980,9 @@ test "serializeTerminalState excludes synchronized output replay" { | |
| 980 | 980 | var stream = term.vtStream(); | |
| 981 | 981 | defer stream.deinit(); | |
| 982 | 982 | ||
| 983 | - | try stream.nextSlice("\x1b[?2004h"); // Bracketed paste | |
| 984 | - | try stream.nextSlice("\x1b[?2026h"); // Synchronized output | |
| 985 | - | try stream.nextSlice("hello"); | |
| 983 | + | stream.nextSlice("\x1b[?2004h"); // Bracketed paste | |
| 984 | + | stream.nextSlice("\x1b[?2026h"); // Synchronized output | |
| 985 | + | stream.nextSlice("hello"); | |
| 986 | 986 | ||
| 987 | 987 | try testing.expect(term.modes.get(.bracketed_paste)); | |
| 988 | 988 | try testing.expect(term.modes.get(.synchronized_output)); |
| ... | ... | @@ -1005,7 +1005,7 @@ fn testCreateTerminal(alloc: std.mem.Allocator, cols: u16, rows: u16, vt_data: [ | |
| 1005 | 1005 | if (vt_data.len > 0) { | |
| 1006 | 1006 | var stream = term.vtStream(); | |
| 1007 | 1007 | defer stream.deinit(); | |
| 1008 | - | try stream.nextSlice(vt_data); | |
| 1008 | + | stream.nextSlice(vt_data); | |
| 1009 | 1009 | } | |
| 1010 | 1010 | return term; | |
| 1011 | 1011 | } |
| ... | ... | @@ -1036,7 +1036,7 @@ fn serializeRoundtrip(alloc: std.mem.Allocator, source: *ghostty_vt.Terminal) !g | |
| 1036 | 1036 | }); | |
| 1037 | 1037 | var stream = dest.vtStream(); | |
| 1038 | 1038 | defer stream.deinit(); | |
| 1039 | - | try stream.nextSlice(serialized); | |
| 1039 | + | stream.nextSlice(serialized); | |
| 1040 | 1040 | return dest; | |
| 1041 | 1041 | } | |
| 1042 | 1042 |
| ... | ... | @@ -1107,11 +1107,11 @@ test "serializeTerminalState with scrollback preserves visible content" { | |
| 1107 | 1107 | var buf: [32]u8 = undefined; | |
| 1108 | 1108 | for (0..80) |i| { | |
| 1109 | 1109 | const line = std.fmt.bufPrint(&buf, "SCROLL_{d}\r\n", .{i}) catch unreachable; | |
| 1110 | - | try stream.nextSlice(line); | |
| 1110 | + | stream.nextSlice(line); | |
| 1111 | 1111 | } | |
| 1112 | 1112 | ||
| 1113 | 1113 | // Clear screen and place markers at specific positions | |
| 1114 | - | try stream.nextSlice("\x1b[2J" ++ | |
| 1114 | + | stream.nextSlice("\x1b[2J" ++ | |
| 1115 | 1115 | "\x1b[2;5HMARK_A" ++ | |
| 1116 | 1116 | "\x1b[6;15HMARK_B" ++ | |
| 1117 | 1117 | "\x1b[10;30HMARK_C" ++ |
| ... | ... | @@ -1149,9 +1149,9 @@ test "serializeTerminalState nested roundtrip preserves content" { | |
| 1149 | 1149 | var buf: [32]u8 = undefined; | |
| 1150 | 1150 | for (0..60) |i| { | |
| 1151 | 1151 | const line = std.fmt.bufPrint(&buf, "SCROLL_{d}\r\n", .{i}) catch unreachable; | |
| 1152 | - | try inner_stream.nextSlice(line); | |
| 1152 | + | inner_stream.nextSlice(line); | |
| 1153 | 1153 | } | |
| 1154 | - | try inner_stream.nextSlice("\x1b[2J" ++ | |
| 1154 | + | inner_stream.nextSlice("\x1b[2J" ++ | |
| 1155 | 1155 | "\x1b[3;10HINNER_A" ++ | |
| 1156 | 1156 | "\x1b[12;25HINNER_B" ++ | |
| 1157 | 1157 | "\x1b[20;5H"); |
| ... | ... | @@ -1173,7 +1173,7 @@ test "serializeTerminalState nested roundtrip preserves content" { | |
| 1173 | 1173 | { | |
| 1174 | 1174 | var outer_stream = outer.vtStream(); | |
| 1175 | 1175 | defer outer_stream.deinit(); | |
| 1176 | - | try outer_stream.nextSlice(inner_serialized); | |
| 1176 | + | outer_stream.nextSlice(inner_serialized); | |
| 1177 | 1177 | } | |
| 1178 | 1178 | ||
| 1179 | 1179 | // Serialize outer (simulates outer daemon re-attach after detach) |
| ... | ... | @@ -1240,9 +1240,9 @@ test "serializeTerminalState scrollback + size mismatch nested roundtrip" { | |
| 1240 | 1240 | var buf: [32]u8 = undefined; | |
| 1241 | 1241 | for (0..80) |i| { | |
| 1242 | 1242 | const line = std.fmt.bufPrint(&buf, "LINE_{d}\r\n", .{i}) catch unreachable; | |
| 1243 | - | try inner_stream.nextSlice(line); | |
| 1243 | + | inner_stream.nextSlice(line); | |
| 1244 | 1244 | } | |
| 1245 | - | try inner_stream.nextSlice("\x1b[2J" ++ | |
| 1245 | + | inner_stream.nextSlice("\x1b[2J" ++ | |
| 1246 | 1246 | "\x1b[3;10HSTRESS_A" ++ | |
| 1247 | 1247 | "\x1b[12;25HSTRESS_B" ++ | |
| 1248 | 1248 | "\x1b[16;20H"); |
| ... | ... | @@ -1264,7 +1264,7 @@ test "serializeTerminalState scrollback + size mismatch nested roundtrip" { | |
| 1264 | 1264 | { | |
| 1265 | 1265 | var outer_stream = outer.vtStream(); | |
| 1266 | 1266 | defer outer_stream.deinit(); | |
| 1267 | - | try outer_stream.nextSlice(inner_ser); | |
| 1267 | + | outer_stream.nextSlice(inner_ser); | |
| 1268 | 1268 | } | |
| 1269 | 1269 | ||
| 1270 | 1270 | var client = try serializeRoundtrip(alloc, &outer); |