build: support native freestanding libghostty-vt

Native freestanding targets cannot emit shared libraries and do not provide an OS page size, stack unwinder, hosted SIMD dependencies, or filesystem-backed Kitty graphics. Build only the static artifact for those targets, define the minimum alignment used for terminal pages, disable hosted-only defaults, and install the public headers with the archive.
This commit is contained in:
Uzair Aftab
2026-08-29 21:13:56 +02:00
parent a5423592cd
commit 3376153a44
5 changed files with 51 additions and 17 deletions

View File

@@ -125,26 +125,36 @@ pub fn build(b: *std.Build) !void {
}
// libghostty-vt
const libghostty_vt_shared = shared: {
const native_freestanding = config.target.result.os.tag == .freestanding and
!config.target.result.cpu.arch.isWasm();
const libghostty_vt_shared: ?buildpkg.GhosttyLibVt = shared: {
if (config.target.result.cpu.arch.isWasm()) {
break :shared try buildpkg.GhosttyLibVt.initWasm(
b,
&mod,
);
}
if (native_freestanding) break :shared null;
break :shared try buildpkg.GhosttyLibVt.initShared(
b,
&mod,
);
};
libghostty_vt_shared.install(b.getInstallStep());
if (libghostty_vt_shared) |shared| {
shared.install(b.getInstallStep());
const type_schema_test = b.addSystemCommand(&.{"python3"});
type_schema_test.addFileArg(b.path("src/terminal/c/types-schema-verify.py"));
type_schema_test.addFileArg(b.path("src/terminal/c/types.schema.json"));
type_schema_test.addFileArg(libghostty_vt_shared.output);
test_lib_vt_schema_step.dependOn(&type_schema_test.step);
const type_schema_test = b.addSystemCommand(&.{"python3"});
type_schema_test.addFileArg(b.path("src/terminal/c/types-schema-verify.py"));
type_schema_test.addFileArg(b.path("src/terminal/c/types.schema.json"));
type_schema_test.addFileArg(shared.output);
test_lib_vt_schema_step.dependOn(&type_schema_test.step);
} else {
try test_lib_vt_schema_step.addError(
"cannot execute the ABI manifest for a native freestanding target",
.{},
);
}
// libghostty-vt static lib
const libghostty_vt_static = try buildpkg.GhosttyLibVt.initStatic(
@@ -167,6 +177,15 @@ pub fn build(b: *std.Build) !void {
libghostty_vt_static.output,
static_lib_name,
).step);
if (native_freestanding) {
b.getInstallStep().dependOn(&b.addInstallDirectory(.{
.source_dir = b.path("include/ghostty"),
.install_dir = .header,
.install_subdir = "ghostty",
.include_extensions = &.{".h"},
}).step);
}
}
// libghostty-vt xcframework (Apple only, universal binary).

View File

@@ -240,9 +240,10 @@ pub fn init(b: *std.Build, appVersion: []const u8, libVersion: []const u8) !Conf
"simd",
"Build with SIMD-accelerated code paths. Results in significant performance improvements.",
) orelse simd: {
// We can't build our SIMD dependencies for Wasm. Note that we may
// still use SIMD features in the Wasm-builds.
if (target.result.cpu.arch.isWasm()) break :simd false;
// We can't build our SIMD dependencies for Wasm or freestanding
// targets. Note that we may still use SIMD features in the Wasm-builds.
if (target.result.cpu.arch.isWasm() or
target.result.os.tag == .freestanding) break :simd false;
break :simd true;
};

View File

@@ -246,7 +246,9 @@ fn initLib(
// Enable PIC so the static library can be linked into PIE
// executables, which is the default on most Linux distributions.
lib.root_module.pic = true;
// Native freestanding targets don't have a dynamic loader and some,
// such as Xtensa, don't support PIC relocations.
lib.root_module.pic = target.result.os.tag != .freestanding;
}
if (target.result.os.tag == .windows) {

View File

@@ -424,6 +424,15 @@ comptime {
pub const std_options: std.Options = opts: {
var options: std.Options = .{};
if (native_freestanding) {
// Freestanding targets don't have an OS page size. We still need an
// alignment for terminal page allocations, and 16 covers everything
// stored in a page without requiring 4 KiB-aligned embedded heaps.
options.page_size_min = 16;
options.page_size_max = 16;
options.allow_stack_tracing = false;
}
if (builtin.target.cpu.arch.isWasm()) {
// In non-debug modes, we want to ship effectively no logging
// warn and lower add ~200KB at the time of this comment.
@@ -464,10 +473,14 @@ pub const std_options: std.Options = opts: {
/// traces on panic, std.debug.print, etc.). These builds are for
/// development, where the roughly 160KB of binary size it costs is
/// worth it.
const debug_machinery: bool = builtin.is_test or switch (builtin.mode) {
.Debug, .ReleaseSafe => true,
.ReleaseFast, .ReleaseSmall => false,
};
const native_freestanding = builtin.target.os.tag == .freestanding and
!builtin.target.cpu.arch.isWasm();
const debug_machinery: bool = !native_freestanding and
(builtin.is_test or switch (builtin.mode) {
.Debug, .ReleaseSafe => true,
.ReleaseFast, .ReleaseSmall => false,
});
/// The panic handler for when this file is the root module.
///

View File

@@ -263,8 +263,7 @@ pub const Options = struct {
/// targets, so it is always disabled there regardless of the
/// feature setting.
pub fn kittyGraphics(self: Options, target: std.Target) bool {
if (target.cpu.arch == .wasm32 and target.os.tag == .freestanding)
return false;
if (target.os.tag == .freestanding) return false;
return self.features.kitty_graphics;
}