build/libghostty-vt: fixed to the build system for programs that embed libghostty-vt and libvaxis (#14191)

Two small patches that don't directly affect Ghostty, but do affect
programs that embed `libghostty-vt` and `libvaxis`, or
any other combination that also uses `uucode`.

AI disclosure: these bugs were discovered/fixed by Claude, but I've
rewritten parts of the patches and the comments.

CC @rockorager
This commit is contained in:
Mitchell Hashimoto
2026-09-09 09:10:49 -07:00
committed by GitHub
2 changed files with 30 additions and 0 deletions

View File

@@ -76,6 +76,12 @@ pub fn init(b: *std.Build, cfg: *const Config) !SharedDeps {
.build_config_path = b.path("src/build/uucode_config.zig"),
}).module("uucode");
// Re-export the uucode module so that Zig programs that embed libgtostty-vt
// can use it. This is necessary to use libraries like libvaxis in
// the embedding program that need uucode as well (libvaxis provides
// -Dexternal_uucode for this).
try b.modules.put(b.allocator, b.dupe("uucode"), uucode_mod);
var result: SharedDeps = .{
.config = cfg,
.help_strings = try .init(b, cfg),

View File

@@ -48,6 +48,30 @@ pub const tables = [_]config.Table{
},
.{
.name = "buildtime",
// Unpacked, because a packed table this size cannot be evaluated
// at comptime by Zig 0.16.0 and this one has to be, whether or not
// anything reads it.
//
// `uucode.get.FieldEnum` is built by walking `@TypeOf(tables)`, so
// instantiating anything that names a field -- `grapheme.Iterator`,
// among others -- materialises every table including this one. In a
// packed layout its rows are a `@bitCast` of a 32000 element `[_]u10`,
// and the compiler gives up on it two different ways depending on
// build options:
//
// tables.zig: error: unable to evaluate comptime expression
// thread panic: TODO implement writeToPackedMemory for more types
//
// Ghostty does not hit this, because its own uses of these fields go
// through the tables generated at build time rather than through
// `uucode.get`. A downstream pairing this config with libvaxis does:
// vaxis measures grapheme widths with `grapheme.Iterator`, so any
// program calling `Vaxis.render` fails to compile.
//
// The cost is the size of a table nothing reads at runtime. The fix
// belongs upstream in uucode or in the compiler; this is what makes
// the pairing build today.
.packing = .unpacked,
.fields = &.{
"width",
"wcwidth_zero_in_grapheme",