mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-04-17 21:12:39 +00:00
build: add iOS slices to lib-vt xcframework
Add iOS device and simulator slices to the xcframework, gated on SDK availability via std.zig.LibCInstallation.findNative. Refactor AppleLibs from a struct with named fields to an EnumMap keyed by ApplePlatform so that adding new platforms only requires extending the enum and its sdk_platforms table. tvOS, watchOS, and visionOS are listed as not yet supported due to Zig stdlib limitations (missing PATH_MAX, mcontext fields).
This commit is contained in:
@@ -156,13 +156,13 @@ pub fn build(b: *std.Build) !void {
|
||||
// Only when building on macOS (not cross-compiling) since
|
||||
// xcodebuild is required.
|
||||
if (builtin.os.tag.isDarwin() and config.target.result.os.tag.isDarwin()) {
|
||||
const universal = try buildpkg.GhosttyLibVt.initStaticAppleUniversal(
|
||||
const apple_libs = try buildpkg.GhosttyLibVt.initStaticAppleUniversal(
|
||||
b,
|
||||
&config,
|
||||
&deps,
|
||||
&mod,
|
||||
);
|
||||
const xcframework = universal.xcframework();
|
||||
const xcframework = buildpkg.GhosttyLibVt.xcframework(&apple_libs, b);
|
||||
b.getInstallStep().dependOn(xcframework.step);
|
||||
}
|
||||
|
||||
|
||||
@@ -102,13 +102,39 @@ pub fn initShared(
|
||||
return initLib(b, zig, .dynamic);
|
||||
}
|
||||
|
||||
/// Build a macOS universal (arm64 + x86_64) static library using lipo.
|
||||
/// Apple platform targets for xcframework slices.
|
||||
pub const ApplePlatform = enum {
|
||||
macos_universal,
|
||||
ios,
|
||||
ios_simulator,
|
||||
// tvOS, watchOS, and visionOS are not yet supported by Zig's
|
||||
// standard library (missing PATH_MAX, mcontext fields, etc.).
|
||||
|
||||
/// Platforms that have device + simulator pairs, gated on SDK detection.
|
||||
const sdk_platforms = [_]struct {
|
||||
os_tag: std.Target.Os.Tag,
|
||||
device: ApplePlatform,
|
||||
simulator: ApplePlatform,
|
||||
}{
|
||||
.{ .os_tag = .ios, .device = .ios, .simulator = .ios_simulator },
|
||||
};
|
||||
};
|
||||
|
||||
/// Static libraries for each Apple platform, keyed by `ApplePlatform`.
|
||||
pub const AppleLibs = std.EnumMap(ApplePlatform, GhosttyLibVt);
|
||||
|
||||
/// Build static libraries for all available Apple platforms.
|
||||
/// Always builds a macOS universal (arm64 + x86_64) fat binary.
|
||||
/// Additional platforms are included if their SDK is detected.
|
||||
pub fn initStaticAppleUniversal(
|
||||
b: *std.Build,
|
||||
cfg: *const Config,
|
||||
deps: *const SharedDeps,
|
||||
zig: *const GhosttyZig,
|
||||
) !GhosttyLibVt {
|
||||
) !AppleLibs {
|
||||
var result: AppleLibs = .{};
|
||||
|
||||
// macOS universal (arm64 + x86_64)
|
||||
const aarch64_zig = try zig.retarget(
|
||||
b,
|
||||
cfg,
|
||||
@@ -121,7 +147,6 @@ pub fn initStaticAppleUniversal(
|
||||
deps,
|
||||
Config.genericMacOSTarget(b, .x86_64),
|
||||
);
|
||||
|
||||
const aarch64 = try initStatic(b, &aarch64_zig);
|
||||
const x86_64 = try initStatic(b, &x86_64_zig);
|
||||
const universal = LipoStep.create(b, .{
|
||||
@@ -130,15 +155,38 @@ pub fn initStaticAppleUniversal(
|
||||
.input_a = aarch64.output,
|
||||
.input_b = x86_64.output,
|
||||
});
|
||||
|
||||
return .{
|
||||
result.put(.macos_universal, .{
|
||||
.step = universal.step,
|
||||
.artifact = universal.step,
|
||||
.kind = .static,
|
||||
.output = universal.output,
|
||||
.dsym = null,
|
||||
.pkg_config = null,
|
||||
};
|
||||
});
|
||||
|
||||
// Additional Apple platforms, each gated on SDK availability.
|
||||
for (ApplePlatform.sdk_platforms) |p| {
|
||||
const target_query: std.Target.Query = .{
|
||||
.cpu_arch = .aarch64,
|
||||
.os_tag = p.os_tag,
|
||||
.os_version_min = Config.osVersionMin(p.os_tag),
|
||||
};
|
||||
if (detectAppleSDK(b.resolveTargetQuery(target_query).result)) {
|
||||
const dev_zig = try zig.retarget(b, cfg, deps, b.resolveTargetQuery(target_query));
|
||||
result.put(p.device, try initStatic(b, &dev_zig));
|
||||
|
||||
const sim_zig = try zig.retarget(b, cfg, deps, b.resolveTargetQuery(.{
|
||||
.cpu_arch = .aarch64,
|
||||
.os_tag = p.os_tag,
|
||||
.os_version_min = Config.osVersionMin(p.os_tag),
|
||||
.abi = .simulator,
|
||||
.cpu_model = .{ .explicit = &std.Target.aarch64.cpu.apple_a17 },
|
||||
}));
|
||||
result.put(p.simulator, try initStatic(b, &sim_zig));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
fn initLib(
|
||||
@@ -336,13 +384,11 @@ fn requiresPrivate(b: *std.Build) []const u8 {
|
||||
return "";
|
||||
}
|
||||
|
||||
/// Create an XCFramework bundle from the static library.
|
||||
/// Create an XCFramework bundle from Apple platform static libraries.
|
||||
pub fn xcframework(
|
||||
lib_vt: *const GhosttyLibVt,
|
||||
apple_libs: *const AppleLibs,
|
||||
b: *std.Build,
|
||||
) *XCFrameworkStep {
|
||||
assert(lib_vt.kind == .static);
|
||||
const b = lib_vt.step.owner;
|
||||
|
||||
// Generate a headers directory with a module map for Swift PM.
|
||||
// We can't use include/ directly because it contains a module map
|
||||
// for GhosttyKit (the macOS app library).
|
||||
@@ -359,18 +405,38 @@ pub fn xcframework(
|
||||
\\}
|
||||
\\
|
||||
);
|
||||
const headers = wf.getDirectory();
|
||||
|
||||
var libraries: [AppleLibs.len]XCFrameworkStep.Library = undefined;
|
||||
var lib_count: usize = 0;
|
||||
for (std.enums.values(ApplePlatform)) |platform| {
|
||||
if (apple_libs.get(platform)) |lib| {
|
||||
libraries[lib_count] = .{
|
||||
.library = lib.output,
|
||||
.headers = headers,
|
||||
.dsym = null,
|
||||
};
|
||||
lib_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return XCFrameworkStep.create(b, .{
|
||||
.name = "ghostty-vt",
|
||||
.out_path = b.pathJoin(&.{ b.install_prefix, "lib/ghostty-vt.xcframework" }),
|
||||
.libraries = &.{.{
|
||||
.library = lib_vt.output,
|
||||
.headers = wf.getDirectory(),
|
||||
.dsym = null,
|
||||
}},
|
||||
.libraries = libraries[0..lib_count],
|
||||
});
|
||||
}
|
||||
|
||||
/// Returns true if the Apple SDK for the given target is installed.
|
||||
fn detectAppleSDK(target: std.Target) bool {
|
||||
_ = std.zig.LibCInstallation.findNative(.{
|
||||
.allocator = std.heap.page_allocator,
|
||||
.target = &target,
|
||||
.verbose = false,
|
||||
}) catch return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn install(
|
||||
self: *const GhosttyLibVt,
|
||||
step: *std.Build.Step,
|
||||
|
||||
Reference in New Issue
Block a user