Closes#12228
Supersedes #12388
**UPDATED** - Also check comments for additional details!
This commit represents the majority of the work necessary to upgrade
Ghostty to use Zig 0.16.0.
At this point, all tests pass under Linux, but more work may be
necessary to get them to build and function on other platforms.
There are some parts of this update that deserve commentary, so that
follows below:
## Expanded use of global state (IO/environment related)
Global state, once generally only used by the C library, has now been
expanded to be used across the project at large. The static local
variable that holds the state has been moved private in its source
container with all attributes that need to be accessed globally gated
behind accessors, most of which guard on testing and send test copies
instead. Use of the global state in non-testing scenarios asserts that
the state has been initialized through `init` naturally through the
optional assertion process.
The rationale for this change is to have a location to store a
general-purpose I/O implementation and environment variables, both of
which are now provided through [Juicy
Main](https://ziglang.org/download/0.16.0/release-notes.html#Juicy-Main)
and hence can no longer be accessed or mutated through stdlib without
use of lower-level system calls and hacks (some of which are employed,
but sparingly).
As the code matures, dependence on global state should naturally slim
down.
We do not allow global state to be used in libghostty-vt. There are
comptime guards that prevent this should compilation of libghostty-vt
end up pulling `global.zig`. This means that as per the last paragraph,
work has already begun to de-couple the codebase from global state where
necessary. Additionally, in some places where environment needs to be
updated and where it can be done in an isolated fashion, environment
maps are used - system-level injection of environment through the use of
`setenv` or `unsetenv` now only happens during early initialization (and
hopefully we can remove these in the future too, especially since they
require re-synchronization of the higher-level environment primitives
after this is done).
## The `lib/compat` Tree
Some stdlib features that have been removed but still either seem they
would be valuable to us or outright complex to move away from
(particularly `SegmentedList`) have been extracted from 0.15.2, updated
as needed, and placed in `src/lib/compat`. The intention again is to
allow for piecemeal migration to more modern implementations or possibly
straight local versions.
This paradigm has also allowed us to add `std.Io.Condition.waitTimeout`,
which incidentally was missed in the 0.16.0 shuffle and has been
re-added for 0.17.0. We can remove this in favor of the upstream when we
eventually migrate to that, obviously.
Note that there was a lot more of this extracted code when this work was
started, but a lot of said code has been removed (namely environment or
process/fd-related functionality).
## translate-c Issues (functional on Linux, Darwin WIP)
There have been a number of C translation issues that we have been
working through through submitted patches and the great help from folks
on the Arocc and Zig side. This is ongoing, with the remaining work to
getting things fixed mainly focused on the MacOS side. Stay tuned for
further developments.
As mentioned at the top, follow comments for more details!
- benchmark: avoid buffers to avoid a memcpy
- build: keep frame pointers on macOS. There was some debug changes from
Zig 0.15 and this helps. Also, Apple actually requires/expects x29 to
always be a frame pointer.
- build/macos: force libSystem symbols instead of compiler-rt
- global: add InitOpts.tool so that ghostty-gen/bench can parse their
own actions in `+action`
- quirks: provide our own vectorized memset. see the comment for more
details why.
- synthetic: fix UB by accessing global.io before it was initialized
- terminal/hash_map: force inline for unique repr types. Zig 0.15
inlined and 0.16 doesn't, measured a huge slowdown in hyperlink
benchmarks.
- terminal: add explicit `@Vector` usage for storing a run of identical cells
as well as for scanning printable cells. This auto-vectorized in Zig
0.15 but not in Zig 0.16. This produces the same assembly.
- unicode: properties and LUT need power-of-two backing integer to avoid
bad LLVM codegen
This commit represents the majority of the work necessary to upgrade
Ghostty to use Zig 0.16.0.
Key parts:
* In addition to its previous responsibilities, the global state now
houses state for global I/O implementations and the process
environment. It is now also utilized in the main application along
with the C library. Where necessary, global state is isolated from key
parts of the implementation (e.g., in libghostty subsystems), and it's
expected that this list will grow.
* We currently manage our own C translation layer where necessary. In
these cases, cImport has been removed in favor of the new external
translate-c package. Due to fixes that have needed be made to properly
translate the dependencies that were swapped out, as mentioned, we
have had to backport fixes from the current translate-c package (and
the upstream Arocc dependency). We will host this ourselves until Zig
0.17.0 is released with these fixes.
* Where necessary (only a small number of cases), some stdlib code from
0.15.2 (and even from 0.17.0) has been taken, adopted, and vendored in
lib/compat.
Co-authored-by: Leah Amelia Chen <hi@pluie.me>
Add a top-level CMakeLists.txt that wraps `zig build lib-vt` so that
CMake-based downstream projects can consume libghostty-vt without
needing to interact with the Zig build system directly. A custom
command triggers the zig build during `cmake --build`, and the
resulting shared library is exposed as an IMPORTED target.
Downstream projects can pull in the library via FetchContent, which
fetches the source and builds it as part of their own CMake build, or
via find_package after a manual install step. The package config
template in dist/cmake/ sets up the ghostty-vt::ghostty-vt target
with proper include paths and macOS rpath handling.
A c-vt-cmake example demonstrates the FetchContent workflow, creating
a terminal, writing VT sequences, and formatting the output as plain
text. CI is updated to auto-discover and build CMake-based examples
alongside the existing Zig-based ones.
This is an update to address common agentic issues I run into,
but the `build.nu` script may be generally helpful to people using
the Nix env since `xcodebuild` is broken by default in Nix due to the
compiler/linker overrides Nix shell does.
This should make testing Flatpak builds a lot easier.
To build, enter `flatpak/` directory and run:
flatpak-builder --repo=repo builddir com.mitchellh.ghostty.yml
alternatively, using org.flatpak.Builder flatpak:
flatpak run -p org.flatpak.Builder \
--repo=repo \
builddir \
com.mitchellh.ghostty.yml
The resulting flatpak can be installed using
flatpak install ./repo com.mitchellh.ghostty
Credit of AppStream metadata goes to @yorickpeterse.
This fixes a regression in 1.1.1/1.1.2 where our PACKAGING docs mention
using `fetch-zig-cache.sh` but it was removed. This commit adds it back,
generating its contents from the build.zig.zon file (via zon2nix which
we use for our Nix packaging).
For packagers, there are no dependency changes: you still need Zig and
POSIX sh. For release time, Ghostty has a new dependency on `jq` but
otherwise the release process is the same. The check-zig-cache.sh script
is updated to generate the new build.zig.zon.txt file.
This brings the internal package more in line with how the nixpkgs
package is built. It also handles recursive dependencies better than the
current system.