Files
jlibghostty/README.md
Gregor Lohaus a03bc2ec48 graal conf
2026-05-27 14:11:20 +02:00

155 lines
3.4 KiB
Markdown

# jlibghostty
Java FFM bindings for Ghostty's `libghostty-vt`.
This targets Java 22+ and uses `java.lang.foreign`, not JNI. The public API is intentionally small while Ghostty's C API is still marked unstable upstream.
## Build
```sh
nix build
```
The default Nix package builds:
- `share/java/jlibghostty-0.1.0-SNAPSHOT.jar`
- `maven/dev/jlibghostty/jlibghostty/0.1.0-SNAPSHOT/...`
The jar contains the host platform `libghostty-vt` under `dev/jlibghostty/native/<platform>/`.
## Gradle Consumer
After `nix build`, another Gradle project can consume the generated Maven repository:
```kotlin
repositories {
maven {
url = uri("/home/anon/Dev/jlibghostty/result/maven")
}
}
dependencies {
implementation("dev.jlibghostty:jlibghostty:0.1.0-SNAPSHOT")
}
tasks.withType<JavaExec>().configureEach {
jvmArgs("--enable-native-access=ALL-UNNAMED")
}
```
## GraalVM Native Image Consumer
`jlibghostty` ships GraalVM reachability metadata at:
```text
META-INF/native-image/dev.jlibghostty/jlibghostty/reachability-metadata.json
```
That metadata registers the FFM downcalls used by this library and includes the bundled native library resource. GraalVM 25 enables Native Image FFM support by default, but the build still needs native access:
```sh
native-image --enable-native-access=ALL-UNNAMED ...
```
If your app uses the module path, prefer:
```sh
native-image --enable-native-access=dev.jlibghostty ...
```
For a Nix-built downstream project, the usual shape is:
```nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
jlibghostty.url = "path:/home/anon/Dev/jlibghostty";
};
outputs = { nixpkgs, jlibghostty, ... }:
let
system = "x86_64-linux";
pkgs = import nixpkgs { inherit system; };
jlib = jlibghostty.packages.${system}.jlibghostty;
in {
packages.${system}.default = pkgs.stdenvNoCC.mkDerivation {
pname = "my-native-app";
version = "0.1.0";
src = ./.;
nativeBuildInputs = [
pkgs.graalvmPackages.graalvm-ce
pkgs.gradle
];
buildPhase = ''
export GRADLE_USER_HOME=$TMPDIR/gradle
gradle --offline -PjlibghosttyMavenRepo=${jlib}/maven installDist
native-image \
--enable-native-access=ALL-UNNAMED \
-cp build/install/my-app/lib/'*' \
-o my-app \
com.example.Main
'';
installPhase = ''
mkdir -p "$out/bin"
cp my-app "$out/bin/"
'';
};
};
}
```
In that downstream Gradle build:
```kotlin
repositories {
mavenCentral()
maven {
url = uri(providers.gradleProperty("jlibghosttyMavenRepo").get())
}
}
dependencies {
implementation("dev.jlibghostty:jlibghostty:0.1.0-SNAPSHOT")
}
```
If the app runs on the module path, use:
```sh
--enable-native-access=dev.jlibghostty
```
## External Native Library
The library normally loads the bundled native `libghostty-vt`. To override it:
```sh
java -Djlibghostty.library.path=/path/to/libghostty-vt.so ...
```
or set:
```sh
export JLIBGHOSTTY_LIBRARY=/path/to/libghostty-vt.so
```
## Example
```java
try (Terminal terminal = Ghostty.open(TerminalOptions.of(80, 24))) {
terminal.write("hello\r\n");
System.out.println(terminal.snapshot());
}
```
## Development Shell
```sh
nix develop
```
The shell provides Java, Gradle, and `JLIBGHOSTTY_LIBRARY` pointing at the Nix-built `libghostty-vt`.