1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
//! GhosttyZig generates the Zig modules that Ghostty exports
//! for downstream usage.
const GhosttyZig = @This();
const std = @import("std");
const Config = @import("Config.zig");
const SharedDeps = @import("SharedDeps.zig");
const TerminalBuildOptions = @import("../terminal/build_options.zig").Options;
/// The `_c`-suffixed modules are built with the C ABI enabled.
vt: *std.Build.Module,
vt_c: *std.Build.Module,
/// The libghostty-vt version
version: std.SemanticVersion,
/// Static library paths for vendored SIMD dependencies. Populated
/// only when the dependencies are built from source (not provided
/// by the system via -Dsystem-integration). Used to produce a
/// combined static archive for downstream consumers.
simd_libs: SharedDeps.LazyPathList,
pub fn init(
b: *std.Build,
cfg: *const Config,
deps: *const SharedDeps,
) !GhosttyZig {
return initInner(b, cfg, deps, "ghostty-vt", "ghostty-vt-c");
}
/// Create a new GhosttyZig with modules retargeted to a different
/// architecture. Used to produce universal (fat) binaries on macOS.
pub fn retarget(
self: *const GhosttyZig,
b: *std.Build,
cfg: *const Config,
deps: *const SharedDeps,
target: std.Build.ResolvedTarget,
) !GhosttyZig {
_ = self;
const retargeted_config = try b.allocator.create(Config);
retargeted_config.* = cfg.*;
retargeted_config.target = target;
const retargeted_deps = try b.allocator.create(SharedDeps);
retargeted_deps.* = try deps.retarget(b, target);
// Use unique module names to avoid collisions with the original target.
const arch_name = @tagName(target.result.cpu.arch);
return initInner(
b,
retargeted_config,
retargeted_deps,
b.fmt("ghostty-vt-{s}", .{arch_name}),
b.fmt("ghostty-vt-c-{s}", .{arch_name}),
);
}
fn initInner(
b: *std.Build,
cfg: *const Config,
deps: *const SharedDeps,
vt_name: []const u8,
vt_c_name: []const u8,
) !GhosttyZig {
// Terminal module build options
var vt_options = cfg.terminalOptions(.lib, cfg.optimize);
vt_options.artifact = .lib;
// We presently don't allow Oniguruma in our Zig module at all.
// We should expose this as a build option in the future so we can
// conditionally do this.
vt_options.oniguruma = false;
var simd_libs: SharedDeps.LazyPathList = .empty;
return .{
.vt = try initVt(
vt_name,
b,
cfg,
deps,
vt_options,
null,
),
.vt_c = try initVt(
vt_c_name,
b,
cfg,
deps,
options: {
var dup = vt_options;
dup.c_abi = true;
break :options dup;
},
&simd_libs,
),
.version = cfg.lib_version,
.simd_libs = simd_libs,
};
}
fn initVt(
name: []const u8,
b: *std.Build,
cfg: *const Config,
deps: *const SharedDeps,
vt_options: TerminalBuildOptions,
simd_libs: ?*SharedDeps.LazyPathList,
) !*std.Build.Module {
// General build options
const general_options = b.addOptions();
try cfg.addOptions(general_options);
const vt = b.addModule(name, .{
.root_source_file = b.path("src/lib_vt.zig"),
.target = cfg.target,
.optimize = cfg.optimize,
// SIMD requires libc. Vendored C++ dependencies are built with
// no-libcxx mode (HWY_NO_LIBCXX / SIMDUTF_NO_LIBCXX) so we
// don't need libcpp. System-provided simdutf headers still
// use C++ stdlib headers, so we need libcpp in that case.
.link_libc = if (cfg.simd) true else null,
.link_libcpp = if (cfg.simd and
b.systemIntegrationOption("simdutf", .{}) and
cfg.target.result.abi != .msvc) true else null,
});
vt.addOptions("build_options", general_options);
vt_options.add(b, vt);
// We always need unicode tables
deps.unicode_tables.addModuleImport(vt);
// We need uucode for grapheme break support
vt.addImport("uucode", deps.uucode_mod);
// We need wuffs for Kitty graphics pixel operations (format
// conversion and alpha blending). Unlike pure Zig dependencies
// its C code is compiled whenever the module is in the build
// graph regardless of analysis, so only wire it in when Kitty
// graphics is actually enabled.
if (vt_options.kittyGraphics(cfg.target.result)) {
if (b.lazyDependency("wuffs", .{
.target = cfg.target,
.optimize = cfg.optimize,
})) |dep| {
vt.addImport("wuffs", dep.module("wuffs"));
}
}
// If SIMD is enabled, add all our SIMD dependencies.
if (cfg.simd) {
try SharedDeps.addSimd(b, vt, simd_libs);
}
return vt;
}
|