mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-04-06 07:38:21 +00:00
build: add Meson wrapper for libghostty-vt
Add Meson build system integration mirroring the existing CMake wrapper. The top-level meson.build delegates to zig build lib-vt using --prefix-lib-dir and --prefix-include-dir to place outputs directly in the Meson build directory, avoiding stamp files and source tree pollution. A sentinel .h output ensures Meson orders the zig build before any downstream compiles. Downstream projects can consume the library either as a Meson subproject via a .wrap file or through pkg-config after install. The dist/meson/README.md documents both approaches. Includes a c-vt-meson example, CI job in test.yml for auto-discovered Meson examples, meson and ninja in the nix devShell, and gitignore updates for Meson build artifacts.
This commit is contained in:
44
.github/workflows/test.yml
vendored
44
.github/workflows/test.yml
vendored
@@ -87,6 +87,7 @@ jobs:
|
||||
- build-dist
|
||||
- build-examples-zig
|
||||
- build-examples-cmake
|
||||
- build-examples-meson
|
||||
- build-flatpak
|
||||
- build-libghostty-vt
|
||||
- build-libghostty-vt-android
|
||||
@@ -175,6 +176,7 @@ jobs:
|
||||
outputs:
|
||||
zig: ${{ steps.list.outputs.zig }}
|
||||
cmake: ${{ steps.list.outputs.cmake }}
|
||||
meson: ${{ steps.list.outputs.meson }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
@@ -187,6 +189,9 @@ jobs:
|
||||
cmake=$(ls example/*/CMakeLists.txt 2>/dev/null | xargs -n1 dirname | xargs -n1 basename | jq -R -s -c 'split("\n") | map(select(. != ""))')
|
||||
echo "$cmake" | jq .
|
||||
echo "cmake=$cmake" >> "$GITHUB_OUTPUT"
|
||||
meson=$(ls example/*/meson.build 2>/dev/null | xargs -n1 dirname | xargs -n1 basename | jq -R -s -c 'split("\n") | map(select(. != ""))')
|
||||
echo "$meson" | jq .
|
||||
echo "meson=$meson" >> "$GITHUB_OUTPUT"
|
||||
|
||||
build-examples-zig:
|
||||
strategy:
|
||||
@@ -261,6 +266,45 @@ jobs:
|
||||
nix develop -c cmake -B build -DFETCHCONTENT_SOURCE_DIR_GHOSTTY=${{ github.workspace }}
|
||||
nix develop -c cmake --build build
|
||||
|
||||
build-examples-meson:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
dir: ${{ fromJSON(needs.list-examples.outputs.meson) }}
|
||||
name: Example ${{ matrix.dir }}
|
||||
runs-on: namespace-profile-ghostty-xsm
|
||||
needs: [test, list-examples]
|
||||
env:
|
||||
ZIG_LOCAL_CACHE_DIR: /zig/local-cache
|
||||
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Setup Cache
|
||||
uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
|
||||
with:
|
||||
path: |
|
||||
/nix
|
||||
/zig
|
||||
|
||||
# Install Nix and use that to run our tests so our environment matches exactly.
|
||||
- uses: cachix/install-nix-action@1ca7d21a94afc7c957383a2d217460d980de4934 # v31.10.1
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
|
||||
with:
|
||||
name: ghostty
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
|
||||
- name: Build Example
|
||||
run: |
|
||||
cd example/${{ matrix.dir }}
|
||||
mkdir -p subprojects
|
||||
ln -s "${{ github.workspace }}" subprojects/ghostty
|
||||
nix develop -c meson setup build
|
||||
nix develop -c meson compile -C build
|
||||
|
||||
build-flatpak:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -10,9 +10,13 @@
|
||||
zig-cache/
|
||||
.zig-cache/
|
||||
zig-out/
|
||||
# CMake
|
||||
build-cmake/
|
||||
CMakeCache.txt
|
||||
CMakeFiles/
|
||||
|
||||
# Meson
|
||||
build-meson/
|
||||
/build.zig.zon.bak
|
||||
/result*
|
||||
/.nixos-test-history
|
||||
|
||||
66
dist/meson/README.md
vendored
Normal file
66
dist/meson/README.md
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
# Meson Support for libghostty-vt
|
||||
|
||||
The top-level `meson.build` wraps the Zig build system so that Meson
|
||||
projects can consume libghostty-vt without invoking `zig build` manually.
|
||||
Running `meson compile` triggers `zig build lib-vt` automatically.
|
||||
|
||||
This means downstream projects do require a working Zig compiler on
|
||||
`PATH` to build, but don't need to know any Zig-specific details.
|
||||
|
||||
## Using a subproject (recommended)
|
||||
|
||||
Create `subprojects/ghostty.wrap`:
|
||||
|
||||
```ini
|
||||
[wrap-git]
|
||||
url = https://github.com/ghostty-org/ghostty.git
|
||||
revision = main
|
||||
depth = 1
|
||||
```
|
||||
|
||||
Then in your project's `meson.build`:
|
||||
|
||||
```meson
|
||||
ghostty_proj = subproject('ghostty')
|
||||
ghostty_vt_dep = ghostty_proj.get_variable('ghostty_vt_dep')
|
||||
|
||||
executable('myapp', 'main.c', dependencies: ghostty_vt_dep)
|
||||
```
|
||||
|
||||
This fetches the Ghostty source, builds libghostty-vt via Zig during your
|
||||
Meson build, and links it into your target. Headers are added to the
|
||||
include path automatically.
|
||||
|
||||
### Using a local checkout
|
||||
|
||||
If you already have the Ghostty source checked out, symlink or copy it
|
||||
into your `subprojects/` directory:
|
||||
|
||||
```shell-session
|
||||
ln -s /path/to/ghostty subprojects/ghostty
|
||||
meson setup build
|
||||
meson compile -C build
|
||||
```
|
||||
|
||||
## Using pkg-config (install-based)
|
||||
|
||||
Build and install libghostty-vt first:
|
||||
|
||||
```shell-session
|
||||
cd /path/to/ghostty
|
||||
meson setup build
|
||||
meson compile -C build
|
||||
meson install -C build
|
||||
```
|
||||
|
||||
Then in your project:
|
||||
|
||||
```meson
|
||||
ghostty_vt_dep = dependency('libghostty-vt')
|
||||
|
||||
executable('myapp', 'main.c', dependencies: ghostty_vt_dep)
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
See `example/c-vt-meson/` for a complete working example.
|
||||
4
example/.gitignore
vendored
4
example/.gitignore
vendored
@@ -2,4 +2,8 @@
|
||||
dist/
|
||||
node_modules/
|
||||
example.wasm*
|
||||
# CMake / Meson
|
||||
build/
|
||||
|
||||
# Meson
|
||||
subprojects/
|
||||
|
||||
42
example/c-vt-meson/README.md
Normal file
42
example/c-vt-meson/README.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# c-vt-meson
|
||||
|
||||
Demonstrates consuming libghostty-vt from a Meson project using a
|
||||
subproject. Creates a terminal, writes VT sequences into it, and
|
||||
formats the screen contents as plain text.
|
||||
|
||||
## Building this example
|
||||
|
||||
Since this example lives inside the Ghostty repo, point the subproject
|
||||
at the local checkout instead of fetching from GitHub:
|
||||
|
||||
```shell-session
|
||||
cd example/c-vt-meson
|
||||
mkdir -p subprojects
|
||||
ln -s ../../.. subprojects/ghostty
|
||||
meson setup build
|
||||
meson compile -C build
|
||||
./build/c_vt_meson
|
||||
```
|
||||
|
||||
## Real World Usage
|
||||
|
||||
Create a `subprojects/ghostty.wrap` file in your project:
|
||||
|
||||
```ini
|
||||
[wrap-git]
|
||||
url = https://github.com/ghostty-org/ghostty.git
|
||||
revision = main
|
||||
depth = 1
|
||||
```
|
||||
|
||||
Then in your `meson.build`:
|
||||
|
||||
```meson
|
||||
ghostty_proj = subproject('ghostty')
|
||||
ghostty_vt_dep = ghostty_proj.get_variable('ghostty_vt_dep')
|
||||
|
||||
executable('myapp', 'src/main.c', dependencies: ghostty_vt_dep)
|
||||
```
|
||||
|
||||
Meson will clone the repository into `subprojects/ghostty/` on first
|
||||
build and invoke `zig build lib-vt` automatically.
|
||||
11
example/c-vt-meson/meson.build
Normal file
11
example/c-vt-meson/meson.build
Normal file
@@ -0,0 +1,11 @@
|
||||
project('c-vt-meson', 'c',
|
||||
version: '0.1.0',
|
||||
meson_version: '>= 1.1.0',
|
||||
)
|
||||
|
||||
ghostty_proj = subproject('ghostty')
|
||||
ghostty_vt_dep = ghostty_proj.get_variable('ghostty_vt_dep')
|
||||
|
||||
executable('c_vt_meson', 'src/main.c',
|
||||
dependencies: ghostty_vt_dep,
|
||||
)
|
||||
52
example/c-vt-meson/src/main.c
Normal file
52
example/c-vt-meson/src/main.c
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ghostty/vt.h>
|
||||
|
||||
int main() {
|
||||
// Create a terminal with a small grid
|
||||
GhosttyTerminal terminal;
|
||||
GhosttyTerminalOptions opts = {
|
||||
.cols = 80,
|
||||
.rows = 24,
|
||||
.max_scrollback = 0,
|
||||
};
|
||||
GhosttyResult result = ghostty_terminal_new(NULL, &terminal, opts);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
// Write some VT-encoded content into the terminal
|
||||
const char *commands[] = {
|
||||
"Hello from a \033[1mMeson\033[0m-built program!\r\n",
|
||||
"Line 2: \033[4munderlined\033[0m text\r\n",
|
||||
"Line 3: \033[31mred\033[0m \033[32mgreen\033[0m \033[34mblue\033[0m\r\n",
|
||||
};
|
||||
for (size_t i = 0; i < sizeof(commands) / sizeof(commands[0]); i++) {
|
||||
ghostty_terminal_vt_write(terminal, (const uint8_t *)commands[i],
|
||||
strlen(commands[i]));
|
||||
}
|
||||
|
||||
// Format the terminal contents as plain text
|
||||
GhosttyFormatterTerminalOptions fmt_opts =
|
||||
GHOSTTY_INIT_SIZED(GhosttyFormatterTerminalOptions);
|
||||
fmt_opts.emit = GHOSTTY_FORMATTER_FORMAT_PLAIN;
|
||||
fmt_opts.trim = true;
|
||||
|
||||
GhosttyFormatter formatter;
|
||||
result = ghostty_formatter_terminal_new(NULL, &formatter, terminal, fmt_opts);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
uint8_t *buf = NULL;
|
||||
size_t len = 0;
|
||||
result = ghostty_formatter_format_alloc(formatter, NULL, &buf, &len);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
printf("Plain text (%zu bytes):\n", len);
|
||||
fwrite(buf, 1, len, stdout);
|
||||
printf("\n");
|
||||
|
||||
free(buf);
|
||||
ghostty_formatter_free(formatter);
|
||||
ghostty_terminal_free(terminal);
|
||||
return 0;
|
||||
}
|
||||
150
meson.build
Normal file
150
meson.build
Normal file
@@ -0,0 +1,150 @@
|
||||
# Meson wrapper for libghostty-vt
|
||||
#
|
||||
# This file delegates to `zig build lib-vt` to produce the shared library,
|
||||
# headers, and pkg-config file. It exists so that Meson-based projects can
|
||||
# consume libghostty-vt without interacting with the Zig build system
|
||||
# directly. However, downstream users do still require `zig` on the PATH.
|
||||
# Please consult the Ghostty docs for the required Zig version:
|
||||
#
|
||||
# https://ghostty.org/docs/install/build
|
||||
#
|
||||
# Building within the Ghostty repo
|
||||
# ---------------------------------
|
||||
#
|
||||
# meson setup build
|
||||
# meson compile -C build
|
||||
# meson install -C build
|
||||
#
|
||||
# Pass extra flags to the Zig build with -Dzig-build-flags:
|
||||
#
|
||||
# meson setup build -Dzig-build-flags='-Demit-macos-app=false'
|
||||
#
|
||||
# Integrating into a downstream Meson project
|
||||
# ---------------------------------------------
|
||||
#
|
||||
# Option 1 — Meson subproject with a .wrap file (recommended):
|
||||
#
|
||||
# Create subprojects/ghostty.wrap:
|
||||
#
|
||||
# [wrap-git]
|
||||
# url = https://github.com/ghostty-org/ghostty.git
|
||||
# revision = main
|
||||
# depth = 1
|
||||
#
|
||||
# Then in your meson.build:
|
||||
#
|
||||
# ghostty_proj = subproject('ghostty')
|
||||
# ghostty_vt_dep = ghostty_proj.get_variable('ghostty_vt_dep')
|
||||
# executable('myapp', 'main.c', dependencies: ghostty_vt_dep)
|
||||
#
|
||||
# Option 2 — pkg-config (after installing to a prefix):
|
||||
#
|
||||
# ghostty_vt_dep = dependency('libghostty-vt')
|
||||
# executable('myapp', 'main.c', dependencies: ghostty_vt_dep)
|
||||
#
|
||||
# See dist/meson/README.md for more details and example/c-vt-meson/ for a
|
||||
# complete working example.
|
||||
|
||||
project('ghostty-vt', 'c',
|
||||
version: '0.1.0',
|
||||
meson_version: '>= 1.1.0',
|
||||
)
|
||||
|
||||
# --- Options ----------------------------------------------------------------
|
||||
|
||||
zig_build_flags = get_option('zig-build-flags')
|
||||
|
||||
# --- Find Zig ----------------------------------------------------------------
|
||||
|
||||
zig = find_program('zig', required: true)
|
||||
message('Found zig: ' + zig.full_path())
|
||||
|
||||
# --- Build via zig build -----------------------------------------------------
|
||||
|
||||
# Use --prefix to direct zig build output into the Meson build directory
|
||||
# so the library is a proper declared output of the custom target.
|
||||
zig_out_dir = meson.current_build_dir() / 'zig-out'
|
||||
|
||||
# Determine library filenames per platform.
|
||||
if host_machine.system() == 'darwin'
|
||||
ghostty_vt_libname = 'libghostty-vt.dylib'
|
||||
ghostty_vt_soname = 'libghostty-vt.0.dylib'
|
||||
ghostty_vt_realname = 'libghostty-vt.0.1.0.dylib'
|
||||
elif host_machine.system() == 'windows'
|
||||
ghostty_vt_libname = 'ghostty-vt.dll'
|
||||
ghostty_vt_realname = 'ghostty-vt.dll'
|
||||
ghostty_vt_soname = ''
|
||||
else
|
||||
ghostty_vt_libname = 'libghostty-vt.so'
|
||||
ghostty_vt_soname = 'libghostty-vt.so.0'
|
||||
ghostty_vt_realname = 'libghostty-vt.so.0.1.0'
|
||||
endif
|
||||
|
||||
# Custom target: run zig build lib-vt with --prefix pointing into the build dir.
|
||||
# Use --prefix-lib-dir to place the library directly in the custom_target
|
||||
# output directory, and --prefix-include-dir for the headers.
|
||||
#
|
||||
# We declare a sentinel .h file as a second output so that Meson creates a
|
||||
# compile-time ordering dependency (Meson only orders compiles before
|
||||
# custom_target outputs that look like headers).
|
||||
zig_build_cmd = [zig, 'build', 'lib-vt',
|
||||
'--prefix-lib-dir', meson.current_build_dir(),
|
||||
'--prefix-include-dir', zig_out_dir / 'include',
|
||||
]
|
||||
if zig_build_flags != ''
|
||||
zig_build_cmd += zig_build_flags.split()
|
||||
endif
|
||||
|
||||
zig_build_lib_vt = custom_target('zig_build_lib_vt',
|
||||
output: [ghostty_vt_realname, 'ghostty-vt-sentinel.h'],
|
||||
command: [
|
||||
'sh', '-c', '"$@" && touch @OUTPUT1@', 'sh',
|
||||
zig_build_cmd,
|
||||
],
|
||||
console: true,
|
||||
install: true,
|
||||
install_dir: [get_option('libdir'), false],
|
||||
)
|
||||
|
||||
# --- Declare dependency for subproject consumers ------------------------------
|
||||
|
||||
ghostty_vt_lib = declare_dependency(
|
||||
compile_args: ['-I' + zig_out_dir / 'include'],
|
||||
sources: zig_build_lib_vt,
|
||||
link_args: [
|
||||
'-L' + meson.current_build_dir(),
|
||||
'-lghostty-vt',
|
||||
'-Wl,-rpath,' + meson.current_build_dir(),
|
||||
],
|
||||
)
|
||||
|
||||
# Expose for subproject() consumers via get_variable('ghostty_vt_dep')
|
||||
ghostty_vt_dep = ghostty_vt_lib
|
||||
|
||||
# --- Install ------------------------------------------------------------------
|
||||
|
||||
if host_machine.system() != 'windows'
|
||||
# Install symlinks
|
||||
meson.add_install_script('sh', '-c',
|
||||
'ln -sf "@0@" "$DESTDIR@1@/@2@"'.format(
|
||||
ghostty_vt_realname,
|
||||
get_option('prefix') / get_option('libdir'),
|
||||
ghostty_vt_soname,
|
||||
),
|
||||
)
|
||||
meson.add_install_script('sh', '-c',
|
||||
'ln -sf "@0@" "$DESTDIR@1@/@2@"'.format(
|
||||
ghostty_vt_soname,
|
||||
get_option('prefix') / get_option('libdir'),
|
||||
ghostty_vt_libname,
|
||||
),
|
||||
)
|
||||
endif
|
||||
|
||||
# Install headers
|
||||
meson.add_install_script('sh', '-c',
|
||||
'cp -r "@0@/include/ghostty" "$DESTDIR@1@/"'.format(
|
||||
zig_out_dir,
|
||||
get_option('prefix') / get_option('includedir'),
|
||||
),
|
||||
)
|
||||
2
meson.options
Normal file
2
meson.options
Normal file
@@ -0,0 +1,2 @@
|
||||
option('zig-build-flags', type: 'string', value: '',
|
||||
description: 'Additional flags to pass to zig build')
|
||||
@@ -9,6 +9,8 @@
|
||||
flatpak-builder,
|
||||
gdb,
|
||||
cmake,
|
||||
meson,
|
||||
ninja,
|
||||
#, glxinfo # unused
|
||||
ncurses,
|
||||
nodejs,
|
||||
@@ -93,6 +95,8 @@ in
|
||||
[
|
||||
# For builds
|
||||
cmake
|
||||
meson
|
||||
ninja
|
||||
doxygen
|
||||
jq
|
||||
llvmPackages_latest.llvm
|
||||
|
||||
Reference in New Issue
Block a user