From cf22cac3fe5eff8dff48fc24337fb4210c5e71bf Mon Sep 17 00:00:00 2001 From: seth Date: Fri, 27 Dec 2024 22:13:41 -0500 Subject: [PATCH 1/7] ghostty: add nixos test --- nixos/tests/terminal-emulators.nix | 2 ++ pkgs/by-name/gh/ghostty/package.nix | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/nixos/tests/terminal-emulators.nix b/nixos/tests/terminal-emulators.nix index 1affcbf3c8f79..3fc820d3ac8ba 100644 --- a/nixos/tests/terminal-emulators.nix +++ b/nixos/tests/terminal-emulators.nix @@ -44,6 +44,8 @@ let germinal.pkg = p: p.germinal; + ghostty.pkg = p: p.ghostty; + gnome-terminal.pkg = p: p.gnome-terminal; guake.pkg = p: p.guake; diff --git a/pkgs/by-name/gh/ghostty/package.nix b/pkgs/by-name/gh/ghostty/package.nix index cbafd16ba3623..83b7ca2cf1c1f 100644 --- a/pkgs/by-name/gh/ghostty/package.nix +++ b/pkgs/by-name/gh/ghostty/package.nix @@ -129,6 +129,12 @@ stdenv.mkDerivation (finalAttrs: { versionCheckProgramArg = [ "--version" ]; + passthru = { + tests = lib.optionalAttrs stdenv.hostPlatform.isLinux { + nixos = nixosTests.terminal-emulators.ghostty; + }; + }; + meta = { homepage = "https://ghostty.org/"; description = "Fast, native, feature-rich terminal emulator pushing modern features"; From cddaf446440be24e78cb85bf74448a46fec1f00f Mon Sep 17 00:00:00 2001 From: seth Date: Fri, 27 Dec 2024 22:54:49 -0500 Subject: [PATCH 2/7] ghostty: add nixosTests.allTerminfo to passthru.tests --- pkgs/by-name/gh/ghostty/package.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/by-name/gh/ghostty/package.nix b/pkgs/by-name/gh/ghostty/package.nix index 83b7ca2cf1c1f..8050f9427e424 100644 --- a/pkgs/by-name/gh/ghostty/package.nix +++ b/pkgs/by-name/gh/ghostty/package.nix @@ -131,6 +131,7 @@ stdenv.mkDerivation (finalAttrs: { passthru = { tests = lib.optionalAttrs stdenv.hostPlatform.isLinux { + inherit (nixosTests) allTerminfo; nixos = nixosTests.terminal-emulators.ghostty; }; }; From aeae376256e9c055f06800d81c64a660aece6fd8 Mon Sep 17 00:00:00 2001 From: seth Date: Fri, 27 Dec 2024 22:53:10 -0500 Subject: [PATCH 3/7] ghostty: factor out dependencies This is meant to make cross platform support a bit easier. The options are kept private as they aren't meant to be touched by end users --- pkgs/by-name/gh/ghostty/package.nix | 82 ++++++++++++++++------------- 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/pkgs/by-name/gh/ghostty/package.nix b/pkgs/by-name/gh/ghostty/package.nix index 8050f9427e424..81a984f1832d1 100644 --- a/pkgs/by-name/gh/ghostty/package.nix +++ b/pkgs/by-name/gh/ghostty/package.nix @@ -1,40 +1,45 @@ { + 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, + # https://github.com/ghostty-org/ghostty/blob/4b4d4062dfed7b37424c7210d1230242c709e990/build.zig#L106 + withAdwaita ? true, }: + 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"; }; + + # 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 + stdenv.mkDerivation (finalAttrs: { pname = "ghostty"; version = "1.0.0"; @@ -48,33 +53,33 @@ stdenv.mkDerivation (finalAttrs: { strictDeps = true; - nativeBuildInputs = [ - glib # Required for `glib-compile-schemas` - ncurses - pandoc - pkg-config - removeReferencesTo - wrapGAppsHook4 - zig_hook - ]; + nativeBuildInputs = + [ + ncurses + pandoc + pkg-config + removeReferencesTo + zig_hook + ] + ++ lib.optionals (appRuntime == "gtk") [ + glib # Required for `glib-compile-schemas` + wrapGAppsHook4 + ]; - buildInputs = [ - bzip2 - expat - fontconfig - freetype - glslang - harfbuzz - libadwaita - libGL - libpng - libX11 - libXcursor - libXi - libXrandr - oniguruma - zlib - ]; + 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 + ]; dontConfigure = true; # doCheck is set to false because unit tests currently fail inside the Nix sandbox. @@ -90,6 +95,11 @@ stdenv.mkDerivation (finalAttrs: { "--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; @@ -121,7 +131,7 @@ stdenv.mkDerivation (finalAttrs: { remove-references-to -t ${finalAttrs.deps} $out/bin/ghostty ''; - NIX_LDFLAGS = [ "-lX11" ]; + NIX_LDFLAGS = lib.optional (appRuntime == "gtk") "-lX11"; nativeInstallCheckInputs = [ versionCheckHook From 7f6a54b155736fa79f973d183982eb722608ef53 Mon Sep 17 00:00:00 2001 From: seth Date: Fri, 27 Dec 2024 22:58:46 -0500 Subject: [PATCH 4/7] ghostty: add optimizationLevel option --- pkgs/by-name/gh/ghostty/package.nix | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkgs/by-name/gh/ghostty/package.nix b/pkgs/by-name/gh/ghostty/package.nix index 81a984f1832d1..ff4cac400b8b2 100644 --- a/pkgs/by-name/gh/ghostty/package.nix +++ b/pkgs/by-name/gh/ghostty/package.nix @@ -21,15 +21,17 @@ versionCheckHook, wrapGAppsHook4, zig_0_13, + # 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, }: 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 From 720556a196d29cbf6e3647c0970322d120222c10 Mon Sep 17 00:00:00 2001 From: seth Date: Sat, 28 Dec 2024 00:37:46 -0500 Subject: [PATCH 5/7] ghostty: cleanup outputs --- pkgs/by-name/gh/ghostty/package.nix | 83 +++++++++++++++++++---------- 1 file changed, 56 insertions(+), 27 deletions(-) diff --git a/pkgs/by-name/gh/ghostty/package.nix b/pkgs/by-name/gh/ghostty/package.nix index ff4cac400b8b2..8caf9fdda7545 100644 --- a/pkgs/by-name/gh/ghostty/package.nix +++ b/pkgs/by-name/gh/ghostty/package.nix @@ -46,6 +46,14 @@ stdenv.mkDerivation (finalAttrs: { pname = "ghostty"; version = "1.0.0"; + outputs = [ + "out" + "man" + "shell_integration" + "terminfo" + "vim" + ]; + src = fetchFromGitHub { owner = "ghostty-org"; repo = "ghostty"; @@ -53,6 +61,10 @@ stdenv.mkDerivation (finalAttrs: { hash = "sha256-AHI1Z4mfgXkNwQA8xYq4tS0/BARbHL7gQUT41vCxQTM="; }; + deps = callPackage ./deps.nix { + name = "${finalAttrs.pname}-cache-${finalAttrs.version}"; + }; + strictDeps = true; nativeBuildInputs = @@ -83,15 +95,6 @@ stdenv.mkDerivation (finalAttrs: { harfbuzz ]; - dontConfigure = true; - # doCheck is set to false because unit tests currently fail inside the Nix sandbox. - doCheck = false; - doInstallCheck = true; - - deps = callPackage ./deps.nix { - name = "${finalAttrs.pname}-cache-${finalAttrs.version}"; - }; - zigBuildFlags = [ "--system" @@ -109,27 +112,46 @@ stdenv.mkDerivation (finalAttrs: { zigCheckFlags = finalAttrs.zigBuildFlags; - outputs = [ - "out" - "terminfo" - "shell_integration" - "vim" - ]; + # 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 + 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 - mv "$out/share/vim/vimfiles" "$vim" - ln -sf "$vim" "$out/share/vim/vimfiles" - ''; - preFixup = '' remove-references-to -t ${finalAttrs.deps} $out/bin/ghostty ''; @@ -139,6 +161,8 @@ stdenv.mkDerivation (finalAttrs: { versionCheckHook ]; + doInstallCheck = true; + versionCheckProgramArg = [ "--version" ]; passthru = { @@ -162,7 +186,12 @@ stdenv.mkDerivation (finalAttrs: { license = lib.licenses.mit; platforms = lib.platforms.linux; mainProgram = "ghostty"; - outputsToInstall = finalAttrs.outputs; + outputsToInstall = [ + "out" + "man" + "shell_integration" + "terminfo" + ]; maintainers = with lib.maintainers; [ jcollie pluiedev From b36e02926f64276c4a7f4df93e04f510b200ba73 Mon Sep 17 00:00:00 2001 From: seth Date: Sat, 28 Dec 2024 00:37:56 -0500 Subject: [PATCH 6/7] ghostty: fix x11 backend Forcing linkage isn't enough for Zig's `dlopen()` call. Let's just point it towards the exact path instead --- pkgs/by-name/gh/ghostty/package.nix | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pkgs/by-name/gh/ghostty/package.nix b/pkgs/by-name/gh/ghostty/package.nix index 8caf9fdda7545..cd47ab7a85198 100644 --- a/pkgs/by-name/gh/ghostty/package.nix +++ b/pkgs/by-name/gh/ghostty/package.nix @@ -61,6 +61,12 @@ stdenv.mkDerivation (finalAttrs: { hash = "sha256-AHI1Z4mfgXkNwQA8xYq4tS0/BARbHL7gQUT41vCxQTM="; }; + # 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");' + ''; + deps = callPackage ./deps.nix { name = "${finalAttrs.pname}-cache-${finalAttrs.version}"; }; @@ -155,8 +161,6 @@ stdenv.mkDerivation (finalAttrs: { remove-references-to -t ${finalAttrs.deps} $out/bin/ghostty ''; - NIX_LDFLAGS = lib.optional (appRuntime == "gtk") "-lX11"; - nativeInstallCheckInputs = [ versionCheckHook ]; From f4d4b224a966a5a380af1fd77469190a00087e86 Mon Sep 17 00:00:00 2001 From: seth Date: Sat, 28 Dec 2024 00:41:35 -0500 Subject: [PATCH 7/7] ghostty: add darwin to meta.platforms --- pkgs/by-name/gh/ghostty/package.nix | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/pkgs/by-name/gh/ghostty/package.nix b/pkgs/by-name/gh/ghostty/package.nix index cd47ab7a85198..dc5e936d2e141 100644 --- a/pkgs/by-name/gh/ghostty/package.nix +++ b/pkgs/by-name/gh/ghostty/package.nix @@ -177,7 +177,6 @@ stdenv.mkDerivation (finalAttrs: { }; 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 @@ -185,21 +184,24 @@ stdenv.mkDerivation (finalAttrs: { 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"; + maintainers = with lib.maintainers; [ + jcollie + pluiedev + getchoo + ]; outputsToInstall = [ "out" "man" "shell_integration" "terminfo" ]; - maintainers = with lib.maintainers; [ - jcollie - pluiedev - getchoo - ]; + platforms = lib.platforms.linux ++ lib.platforms.darwin; + # Issues finding the SDK in the sandbox + broken = stdenv.hostPlatform.isDarwin; }; })