Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,13 @@ jobs:
- name: Check pkg-config path
if: runner.os == 'Linux'
run: |
nix develop --command cargo build -p libghostty-vt-sys
PKG_CONFIG_PATH=$(find target/debug/build -path '*/out/ghostty-install/share/pkgconfig' | head -1)
test -n "$PKG_CONFIG_PATH"
export PKG_CONFIG_PATH
nix develop --command cargo check -p libghostty-vt-sys --features pkg-config
test -f result/share/pkgconfig/libghostty-vt-static.pc
PKG_CONFIG_PATH="$PWD/result/share/pkgconfig" \
nix develop --command env \
-u GHOSTTY_SOURCE_DIR \
-u GHOSTTY_ZIG_SYSTEM_DIR \
cargo check -p libghostty-vt-sys --no-default-features --features pkg-config

- name: Run libghostty-vt tests under Valgrind
if: matrix.name == 'Linux x86_64'
run: nix build .#checks.x86_64-linux.ci-valgrind --print-build-logs
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ Vendored builds derive Zig's optimize mode from Cargo's profile: dev builds use
`Debug`, size-optimized builds use `ReleaseSmall`, and other release builds use
`ReleaseFast`. Set `LIBGHOSTTY_VT_SYS_OPTIMIZE` to `Debug`, `ReleaseSafe`,
`ReleaseFast`, or `ReleaseSmall` to override that choice explicitly.
Set `LIBGHOSTTY_VT_SYS_SIMD=false` to pass Ghostty's `-Dsimd=false` option and
build scalar code paths only. The Nix output `.#libghostty-vt-non-simd` uses
that mode, and the Valgrind CI check combines it with Zig `Debug` builds.

The `pkg-config` path is opt-in. If you enable `libghostty-vt-sys/pkg-config`,
the build will prefer an installed `libghostty-vt` discovered through
Expand Down
21 changes: 21 additions & 0 deletions crates/libghostty-vt-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ fn main() {
let link_mode = LinkMode::current();

println!("cargo:rerun-if-env-changed=LIBGHOSTTY_VT_SYS_OPTIMIZE");
println!("cargo:rerun-if-env-changed=LIBGHOSTTY_VT_SYS_SIMD");
println!("cargo:rerun-if-env-changed=GHOSTTY_SOURCE_DIR");
println!("cargo:rerun-if-env-changed=GHOSTTY_ZIG_SYSTEM_DIR");
println!("cargo:rerun-if-env-changed=TARGET");
Expand Down Expand Up @@ -126,12 +127,14 @@ fn build_vendored(link_mode: LinkMode) {
let zig_global_cache_dir = out_dir.join("zig-global-cache");

let optimize = zig_optimize_mode();
let simd = zig_simd_enabled();

let mut build = Command::new("zig");
build
.arg("build")
.arg("-Demit-lib-vt")
.arg(format!("-Doptimize={optimize}"))
.arg(format!("-Dsimd={simd}"))
.arg("-Demit-xcframework=false")
.arg("-Dapp-runtime=none")
.arg("--prefix")
Expand Down Expand Up @@ -316,6 +319,24 @@ fn zig_optimize_mode() -> &'static str {
}
}

/// Decide whether to build Ghostty's SIMD-accelerated code paths.
///
/// Ghostty exposes this as `zig build -Dsimd=...`. Valgrind builds should turn
/// it off so the generated library uses scalar fallbacks instead of pulling in
/// the C++ highway/simdutf implementation block.
fn zig_simd_enabled() -> bool {
match env::var("LIBGHOSTTY_VT_SYS_SIMD") {
Ok(value) => match value.as_str() {
"1" | "true" | "True" | "TRUE" => true,
"0" | "false" | "False" | "FALSE" => false,
other => {
panic!("LIBGHOSTTY_VT_SYS_SIMD must be one of true, false, 1, 0 (got '{other}')")
}
},
Err(_) => true,
}
}

/// Clone ghostty at the pinned commit into OUT_DIR/ghostty-src.
/// Reuses an existing clone if the commit matches.
fn fetch_ghostty(out_dir: &Path) -> PathBuf {
Expand Down
82 changes: 80 additions & 2 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,90 @@
};

cargoArtifacts = craneLib.buildDepsOnly commonArgs;
nonSimdCargoArtifacts = craneLib.buildDepsOnly (
commonArgs
// {
pname = "libghostty-rs-non-simd-deps";
LIBGHOSTTY_VT_SYS_SIMD = "false";
}
);
ciValgrindCargoArtifacts = craneLib.buildDepsOnly (
commonArgs
// {
pname = "libghostty-rs-ci-valgrind-deps";
cargoExtraArgs = "--locked -p libghostty-vt";
cargoTestExtraArgs = "--no-run";
CARGO_PROFILE = "";

# The Valgrind check must not inherit ReleaseFast Zig artifacts from
# the normal package build. Debug keeps both Rust and Zig codegen in
# Valgrind's supported instruction set and gives better reports.
LIBGHOSTTY_VT_SYS_OPTIMIZE = "Debug";
LIBGHOSTTY_VT_SYS_SIMD = "false";
}
);

application = craneLib.buildPackage (
commonArgs
// {
inherit cargoArtifacts;
postInstall = ''
ghostty_install=$(find target -path '*/out/ghostty-install' -type d | head -1)
if [ -z "$ghostty_install" ]; then
echo "expected Cargo build script to install libghostty-vt into OUT_DIR" >&2
exit 1
fi
ghostty_install=$(realpath "$ghostty_install")

cp -R "$ghostty_install"/. "$out"/
substituteInPlace "$out"/share/pkgconfig/*.pc \
--replace-fail "prefix=$ghostty_install" "prefix=$out"
'';
}
);

libghosttyVtNonSimd = craneLib.buildPackage (
commonArgs
// {
cargoArtifacts = nonSimdCargoArtifacts;
pname = "libghostty-vt-non-simd";
LIBGHOSTTY_VT_SYS_SIMD = "false";
}
);

ciValgrind = craneLib.buildPackage (
commonArgs
// {
cargoArtifacts = ciValgrindCargoArtifacts;
pname = "libghostty-rs-ci-valgrind";
cargoBuildCommand = "";
cargoTestCommand = "cargo valgrind test";
cargoExtraArgs = "--locked -p libghostty-vt";
cargoTestExtraArgs = "-- --test-threads=1";
CARGO_PROFILE = "";
LIBGHOSTTY_VT_SYS_OPTIMIZE = "Debug";
LIBGHOSTTY_VT_SYS_SIMD = "false";
nativeBuildInputs = commonArgs.nativeBuildInputs ++ [
pkgs.cargo-valgrind
pkgs.valgrind
];

installPhaseCommand = "mkdir -p $out";
}
);
in {
packages.default = application;
packages = {
default = application;
libghostty-vt-non-simd = libghosttyVtNonSimd;
};

checks.default = application;
checks =
{
default = application;
}
// pkgs.lib.optionalAttrs (system == "x86_64-linux") {
ci-valgrind = ciValgrind;
};

devShells.default = craneLib.devShell {
packages = [
Expand All @@ -137,6 +210,9 @@
pkgs.cmake
pkgs.ninja
] ++ pkgs.lib.optionals pkgs.stdenv.hostPlatform.isLinux [
# Valgrind is Linux-only here. Keep it in the development shell so
# CI and local Linux users exercise the same memory-checking path.
pkgs.valgrind
pkgs.libx11
pkgs.libxcursor
pkgs.libxrandr
Expand All @@ -145,6 +221,8 @@
pkgs.libGL
pkgs.libxkbcommon
pkgs.wayland
] ++ pkgs.lib.optionals (system == "x86_64-linux") [
pkgs.cargo-valgrind
];

shellHook = ''
Expand Down
Loading