Ghostty 源码拆解

libghostty 与 C API:把终端核心变成库

libghostty、libghostty-vt、C ABI、WASM 和嵌入约束

libghostty 与 C API:把终端核心变成库

Ghostty 的库化不是把 GUI 可执行文件改成 shared library。项目在构建图上区分完整 libghostty、更窄的 libghostty-vt、benchmark API、config API 和 WASM 入口,使不同宿主只链接自己需要的部分。

两种库

libghostty-vt

src/lib_vt.zig 导出 PagePageListScreenScreenSetTerminalTerminalStream 等 VT 核心类型。它不要求完整窗口系统,目标可以是 macOS、Linux、Windows 甚至 wasm32-freestanding。适合做终端解析、协议测试、Web 终端和其他 emulator 的底层。

libghostty

更完整的库还包括 Surface、renderer、font、runtime callbacks 和 app/surface C API。源码注释也很诚实:当前 C API 主要服务 macOS 嵌入,未来才可能成为通用 embedding API。阅读 API 时要区分“当前被 GhosttyKit 使用”和“设计上理论可被任何宿主使用”。

C ABI 的装配方式

src/main_c.zig 在 comptime 阶段强制引用 config C API、embedded runtime C API、benchmark API 和平台需要的导出,确保链接器不会把只通过反射/类型引用的函数裁掉。顶层导出包括:

  • ghostty_init:初始化全局状态;
  • ghostty_cli_try_action:运行 CLI action;
  • ghostty_info:版本与 build mode;
  • ghostty_translate:语言翻译;
  • ghostty_string_free:释放 core 分配的字符串;
  • config/app/surface 的生命周期、事件和查询函数。

这是一条重要的 ABI 纪律:C 侧只能看到稳定布局的 extern struct、明确 ownership 的字符串和函数;Zig 内部的 allocator、union 细节不能直接泄露。

字符串 ownership

ghostty_string_s 同时记录 pointer、length、是否有 sentinel。ghostty_string_free 根据 sentinel 选择正确的 slice,再用 Ghostty global allocator 释放。Swift wrapper 不能随便 free(),而要调用对应的 API;否则分配器或零结尾约束可能不匹配。

生命周期与线程

embedded 宿主需要遵循类似的顺序:

ghostty_init
  → config_new/load/finalize
  → app_new(runtime_config, config)
  → surface_new(...)
  → app_tick / surface events / redraw callbacks
  → surface_free
  → app_free

macOS Swift 的 Surface.deinit 特别说明:若不在主线程,要把 ghostty_surface_free 重新投递到 MainActor。这个细节体现了 API 并不是“任意线程可调用”;宿主必须把 core 的生命周期和平台 UI 线程规则一起实现。

WASM 入口

src/config/Wasm.zigsrc/os/wasm 和 WebGL/font web canvas 相关模块说明项目把“可移植终端语义”和“桌面 GUI”分开了。WASM 目标通常只需要配置、VT parser、字体/渲染的 web backend,不应假设 POSIX PTY 存在。

适合嵌入的边界

如果要在另一个应用里嵌入 Ghostty,优先选择:

  1. 只要 parser/state:使用 libghostty-vt
  2. 要完整 terminal surface:使用 libghostty 的 embedded runtime contract;
  3. 自己掌控窗口和事件:实现 userdata + callback + tick + redraw;
  4. 不要直接依赖 src/ 的内部 Zig 类型作为 ABI。

现实的限制

C API 的存在不等于 API 已经稳定。README 明确指出 libghostty 仍在演进,API signatures 可能变化;构建脚本也把库、XCFramework、WASM 和完整 app 分成不同 step。二次开发应把版本锁定、C header 生成和回调契约测试纳入自己的构建。

On this page