-
-
Notifications
You must be signed in to change notification settings - Fork 14.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ghostty: add nixos tests, add build options, fix x11 backend #368726
Changes from all commits
cf22cac
cddaf44
aeae376
7f6a54b
720556a
b36e029
f4d4b22
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,153 +1,207 @@ | ||
{ | ||
lib, | ||
stdenv, | ||
bzip2, | ||
callPackage, | ||
expat, | ||
fetchFromGitHub, | ||
fontconfig, | ||
freetype, | ||
glib, | ||
glslang, | ||
harfbuzz, | ||
lib, | ||
libadwaita, | ||
libGL, | ||
libpng, | ||
libX11, | ||
libXcursor, | ||
libXi, | ||
libXrandr, | ||
libadwaita, | ||
ncurses, | ||
nixosTests, | ||
oniguruma, | ||
pandoc, | ||
pkg-config, | ||
removeReferencesTo, | ||
stdenv, | ||
versionCheckHook, | ||
wrapGAppsHook4, | ||
zig_0_13, | ||
zlib, | ||
# Usually you would override `zig.hook` with this, but we do that internally | ||
# since upstream recommends a non-default level | ||
# https://github.com/ghostty-org/ghostty/blob/4b4d4062dfed7b37424c7210d1230242c709e990/PACKAGING.md#build-options | ||
optimizeLevel ? "ReleaseFast", | ||
# https://github.com/ghostty-org/ghostty/blob/4b4d4062dfed7b37424c7210d1230242c709e990/build.zig#L106 | ||
withAdwaita ? true, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also don't think that there's any value in letting the user build the package without Adwaita. It can be disabled at runtime if the user really needs to. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should also be noted that there are a number of developers that work on the GTK frontend that want to eliminate the possibility of building without Adwaita. There are many features that don't work at all without Adwaita (tab overviews is the big one) and other features have to be implemented twice, once for plain GTK, and once for GTK+Adwaita. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can be useful to do if you want to minimise your dependency tree. Though you'd be hard-pressed to get rid of Adwaita on any desktop system. Still, use-cases where one doesn't need any fancy UI elements at all exist. The first thing I did when trying out ghostty was to disable the bar. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think upstream may disagree with you there, at least for now. Why else would this be an option?
If they do it'll be easy to remove. I don't see much reason in hiding this option in the meantime |
||
}: | ||
|
||
let | ||
# Ghostty needs to be built with --release=fast, --release=debug and | ||
# --release=safe enable too many runtime safety checks. | ||
zig_hook = zig_0_13.hook.overrideAttrs { | ||
zig_default_flags = "-Dcpu=baseline -Doptimize=ReleaseFast --color off"; | ||
zig_default_flags = "-Dcpu=baseline -Doptimize=${optimizeLevel} --color off"; | ||
}; | ||
|
||
# https://github.com/ghostty-org/ghostty/blob/4b4d4062dfed7b37424c7210d1230242c709e990/src/apprt.zig#L72-L76 | ||
appRuntime = if stdenv.hostPlatform.isLinux then "gtk" else "none"; | ||
# https://github.com/ghostty-org/ghostty/blob/4b4d4062dfed7b37424c7210d1230242c709e990/src/font/main.zig#L94 | ||
fontBackend = if stdenv.hostPlatform.isDarwin then "coretext" else "fontconfig_freetype"; | ||
# https://github.com/ghostty-org/ghostty/blob/4b4d4062dfed7b37424c7210d1230242c709e990/src/renderer.zig#L51-L52 | ||
renderer = if stdenv.hostPlatform.isDarwin then "metal" else "opengl"; | ||
in | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think that letting the user modify these options really adds anything but more work for us (or the Ghostty developers) when people inevitably choose incompatible or non-functional combinations and then report bugs. Ghostty will automatically choose the right runtimes, backends, and renderers depending on the platform. These should be removed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
While I very much disagree with this (people can already set these flags with The main goal here is to avoid dumping all of our dependencies into broad There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the goal is only platform support, you should simply make the deps optional depending on platform. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As I said
I believe this makes future platform support much easier, as chances are BSD support for example would probably use similar, but not the exact same features and dependencies; separating these features into their own distinct booleans makes mixing and matching these relatively simple and a lot more comprehensible. This is also modeled almost exactly after how the build scripts determine whether or not the dependencies are needed, which I think is a good thing to follow |
||
|
||
stdenv.mkDerivation (finalAttrs: { | ||
pname = "ghostty"; | ||
version = "1.0.0"; | ||
|
||
outputs = [ | ||
"out" | ||
"man" | ||
"shell_integration" | ||
"terminfo" | ||
"vim" | ||
]; | ||
|
||
src = fetchFromGitHub { | ||
owner = "ghostty-org"; | ||
repo = "ghostty"; | ||
tag = "v${finalAttrs.version}"; | ||
hash = "sha256-AHI1Z4mfgXkNwQA8xYq4tS0/BARbHL7gQUT41vCxQTM="; | ||
}; | ||
|
||
strictDeps = true; | ||
|
||
nativeBuildInputs = [ | ||
glib # Required for `glib-compile-schemas` | ||
ncurses | ||
pandoc | ||
pkg-config | ||
removeReferencesTo | ||
wrapGAppsHook4 | ||
zig_hook | ||
]; | ||
|
||
buildInputs = [ | ||
bzip2 | ||
expat | ||
fontconfig | ||
freetype | ||
glslang | ||
harfbuzz | ||
libadwaita | ||
libGL | ||
libpng | ||
libX11 | ||
libXcursor | ||
libXi | ||
libXrandr | ||
oniguruma | ||
zlib | ||
]; | ||
|
||
dontConfigure = true; | ||
# doCheck is set to false because unit tests currently fail inside the Nix sandbox. | ||
doCheck = false; | ||
doInstallCheck = true; | ||
# Avoid using runtime hacks to help find X11 | ||
postPatch = lib.optionalString (appRuntime == "gtk") '' | ||
substituteInPlace src/apprt/gtk/x11.zig \ | ||
--replace-warn 'std.DynLib.open("libX11.so");' 'std.DynLib.open("${lib.getLib libX11}/lib/libX11.so");' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Out of curiosity: any idea why this zig lookup doesn't succeed without forcing the full path? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not really sure tbh. It could be the dlopen implementation internally; usually forcing linkage at runtime via Won't be a problem once ghostty-org/ghostty#3857 gets into a stable tag though ;) |
||
''; | ||
|
||
getchoo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
deps = callPackage ./deps.nix { | ||
name = "${finalAttrs.pname}-cache-${finalAttrs.version}"; | ||
}; | ||
|
||
strictDeps = true; | ||
|
||
nativeBuildInputs = | ||
[ | ||
ncurses | ||
pandoc | ||
pkg-config | ||
removeReferencesTo | ||
zig_hook | ||
] | ||
++ lib.optionals (appRuntime == "gtk") [ | ||
glib # Required for `glib-compile-schemas` | ||
wrapGAppsHook4 | ||
]; | ||
|
||
buildInputs = | ||
[ | ||
glslang | ||
oniguruma | ||
] | ||
++ lib.optional (appRuntime == "gtk" && withAdwaita) libadwaita | ||
++ lib.optional (appRuntime == "gtk") libX11 | ||
++ lib.optional (renderer == "opengl") libGL | ||
++ lib.optionals (fontBackend == "fontconfig_freetype") [ | ||
bzip2 | ||
fontconfig | ||
freetype | ||
harfbuzz | ||
]; | ||
|
||
zigBuildFlags = | ||
[ | ||
"--system" | ||
"${finalAttrs.deps}" | ||
"-Dversion-string=${finalAttrs.version}" | ||
|
||
"-Dapp-runtime=${appRuntime}" | ||
"-Dfont-backend=${fontBackend}" | ||
"-Dgtk-adwaita=${lib.boolToString withAdwaita}" | ||
"-Drenderer=${renderer}" | ||
] | ||
++ lib.mapAttrsToList (name: package: "-fsys=${name} --search-prefix ${lib.getLib package}") { | ||
inherit glslang; | ||
}; | ||
|
||
zigCheckFlags = finalAttrs.zigBuildFlags; | ||
|
||
outputs = [ | ||
"out" | ||
"terminfo" | ||
"shell_integration" | ||
"vim" | ||
getchoo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
]; | ||
# Unit tests currently fail inside the sandbox | ||
doCheck = false; | ||
|
||
postInstall = '' | ||
mkdir -p "$terminfo/share" | ||
mv "$out/share/terminfo" "$terminfo/share/terminfo" | ||
ln -sf "$terminfo/share/terminfo" "$out/share/terminfo" | ||
/** | ||
Ghostty really likes all of it's resources to be in the same directory, so link them back after we split them | ||
|
||
mkdir -p "$shell_integration" | ||
mv "$out/share/ghostty/shell-integration" "$shell_integration/shell-integration" | ||
ln -sf "$shell_integration/shell-integration" "$out/share/ghostty/shell-integration" | ||
- https://github.com/ghostty-org/ghostty/blob/4b4d4062dfed7b37424c7210d1230242c709e990/src/os/resourcesdir.zig#L11-L52 | ||
- https://github.com/ghostty-org/ghostty/blob/4b4d4062dfed7b37424c7210d1230242c709e990/src/termio/Exec.zig#L745-L750 | ||
- https://github.com/ghostty-org/ghostty/blob/4b4d4062dfed7b37424c7210d1230242c709e990/src/termio/Exec.zig#L818-L834 | ||
|
||
terminfo and shell integration should also be installable on remote machines | ||
|
||
```nix | ||
{ pkgs, ... }: { | ||
environment.systemPackages = [ pkgs.ghostty.terminfo ]; | ||
|
||
programs.bash = { | ||
interactiveShellInit = '' | ||
if [[ "$TERM" == "xterm-ghostty" ]]; then | ||
builtin source ${pkgs.ghostty.shell_integration}/bash/ghostty.bash | ||
fi | ||
''; | ||
}; | ||
} | ||
``` | ||
*/ | ||
postFixup = '' | ||
ln -s $man/share/man $out/share/man | ||
|
||
moveToOutput share/terminfo $terminfo | ||
getchoo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
ln -s $terminfo/share/terminfo $out/share/terminfo | ||
|
||
mv $out/share/ghostty/shell-integration $shell_integration | ||
ln -s $shell_integration $out/share/ghostty/shell-integration | ||
|
||
mv $out/share/vim/vimfiles $vim | ||
rmdir $out/share/vim | ||
ln -s $vim $out/share/vim-plugins | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It needs to be added to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's already installed at $out/share/vim-plugins whenever the ghostty binary is. There's no point installing the plugin itself to the a profile; that only belongs in plugin wrappers, etc. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's just vim that needs the extra config and adding that config 'installs' the output. Neovim appears to just work. |
||
|
||
mv "$out/share/vim/vimfiles" "$vim" | ||
ln -sf "$vim" "$out/share/vim/vimfiles" | ||
''; | ||
|
||
preFixup = '' | ||
remove-references-to -t ${finalAttrs.deps} $out/bin/ghostty | ||
''; | ||
|
||
NIX_LDFLAGS = [ "-lX11" ]; | ||
|
||
nativeInstallCheckInputs = [ | ||
versionCheckHook | ||
]; | ||
|
||
doInstallCheck = true; | ||
|
||
versionCheckProgramArg = [ "--version" ]; | ||
|
||
passthru = { | ||
tests = lib.optionalAttrs stdenv.hostPlatform.isLinux { | ||
getchoo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
inherit (nixosTests) allTerminfo; | ||
nixos = nixosTests.terminal-emulators.ghostty; | ||
}; | ||
}; | ||
|
||
meta = { | ||
homepage = "https://ghostty.org/"; | ||
description = "Fast, native, feature-rich terminal emulator pushing modern features"; | ||
longDescription = '' | ||
Ghostty is a terminal emulator that differentiates itself by being | ||
fast, feature-rich, and native. While there are many excellent terminal | ||
emulators available, they all force you to choose between speed, | ||
features, or native UIs. Ghostty provides all three. | ||
''; | ||
homepage = "https://ghostty.org/"; | ||
downloadPage = "https://ghostty.org/download"; | ||
|
||
license = lib.licenses.mit; | ||
platforms = lib.platforms.linux; | ||
mainProgram = "ghostty"; | ||
outputsToInstall = finalAttrs.outputs; | ||
maintainers = with lib.maintainers; [ | ||
jcollie | ||
pluiedev | ||
getchoo | ||
]; | ||
outputsToInstall = [ | ||
"out" | ||
"man" | ||
"shell_integration" | ||
"terminfo" | ||
]; | ||
platforms = lib.platforms.linux ++ lib.platforms.darwin; | ||
# Issues finding the SDK in the sandbox | ||
broken = stdenv.hostPlatform.isDarwin; | ||
}; | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need this? It doesn't sound like any user could possibly want to use anything but ReleaseFast.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was asked for previously. I think it would also make sense to expose this directly, as the way we override
zig.hook
makes it difficult to change this flag directlyI've also found it useful in iterating on this expression at least :p