Files
ghostty/src/build/GhosttyZig.zig
Mitchell Hashimoto 05fb57dd40 build: emit xcframework for libghostty-vt on macOS
On Darwin targets, the build now automatically produces a universal
(arm64 + x86_64) XCFramework at lib/ghostty-vt.xcframework under
the install prefix. This bundles the fat static library with headers
so consumers using Xcode or Swift PM can link libghostty-vt directly.
2026-04-06 14:07:19 -07:00

146 lines
4.2 KiB
Zig

//! 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);
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 require libc/libcpp (both) but otherwise we don't care.
// On MSVC, we must not use linkLibCpp because Zig passes
// -nostdinc++ and adds its bundled libc++/libc++abi headers
// which conflict with MSVC's C++ runtime. The MSVC SDK dirs
// added via link_libc contain both C and C++ headers.
.link_libc = if (cfg.simd) true else null,
.link_libcpp = if (cfg.simd 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
deps.addUucode(b, vt, cfg.target, cfg.optimize);
// If SIMD is enabled, add all our SIMD dependencies.
if (cfg.simd) {
try SharedDeps.addSimd(b, vt, simd_libs);
}
return vt;
}