From 02ed0171ad2f1e6b9287eaa25908879dcfff069f Mon Sep 17 00:00:00 2001 From: einliterflasche Date: Fri, 8 May 2026 12:16:51 +0200 Subject: [PATCH 1/4] build: setup nix dependencies --- .envrc | 1 + .gitignore | 2 + flake.nix | 15 +++++++ shell.nix | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 138 insertions(+) create mode 100644 .envrc create mode 100644 flake.nix create mode 100644 shell.nix diff --git a/.envrc b/.envrc new file mode 100644 index 0000000000..1d953f4bd7 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use nix diff --git a/.gitignore b/.gitignore index d499b9c3f3..fb47aac4d9 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,5 @@ libp2p-rendezvous-node/rendezvous-data rust-electrum-client/ rust-libp2p/ bdk/ + +.direnv/ diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000000..65055b1a0e --- /dev/null +++ b/flake.nix @@ -0,0 +1,15 @@ +{ + description = "xmr-btc-swap / eigenwallet build environment"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils }: + flake-utils.lib.eachDefaultSystem (system: + let pkgs = import nixpkgs { inherit system; }; + in { + devShells.default = import ./shell.nix { inherit pkgs; }; + }); +} diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000000..c16e3c3f8f --- /dev/null +++ b/shell.nix @@ -0,0 +1,120 @@ +{ pkgs ? import (builtins.fetchTarball { + url = "https://github.com/NixOS/nixpkgs/archive/refs/heads/nixos-25.05.tar.gz"; + }) { } +}: + +let + # monero-depends/hosts/linux.mk hardcodes the Debian-style triple + # `x86_64-linux-gnu-` when the build host is x86. Nixpkgs ships + # those tools under `x86_64-unknown-linux-gnu-*` (or unprefixed), so + # without these wrappers `configure` reports "C compiler cannot create + # executables" even though the toolchain is fine. + prefixWrapper = from: tool: pkgs.writeShellScriptBin "x86_64-linux-gnu-${tool}" + ''exec ${from}/bin/${tool} "$@"''; + + moneroDependsToolchain = pkgs.symlinkJoin { + name = "monero-depends-toolchain"; + paths = + map (prefixWrapper pkgs.gcc) [ "gcc" "g++" "cpp" "cc" ] + ++ map (prefixWrapper pkgs.binutils) + [ "ar" "ranlib" "nm" "strip" "ld" "as" "objcopy" "objdump" "readelf" ]; + }; + + # Link-time deps for src-tauri and upstream Rust crates. These are found + # via pkg-config + nix-managed RPATH; do NOT add them to LD_LIBRARY_PATH + # because that overrides RPATH and can shadow binaries built against a + # newer openssl (e.g. curl's ngtcp2 module). + tauriLinkLibs = with pkgs; [ + glib + gtk3 + gdk-pixbuf + cairo + pango + atkmm + at-spi2-atk + libsoup_3 + webkitgtk_4_1 + librsvg + libayatana-appindicator + openssl + zlib + ]; + + # Subset that WebKitGTK / GTK dlopen at runtime (tray icon, SVG pixbuf + # loaders, webview plugins). These must be reachable via LD_LIBRARY_PATH. + tauriRuntimeLibs = with pkgs; [ + webkitgtk_4_1 + libsoup_3 + librsvg + libayatana-appindicator + gdk-pixbuf + ]; +in +pkgs.mkShell { + # Tools invoked during the build (compilers, codegen, fetchers). + # Mirrors DEPS_BUILD_LINUX from .github/actions/set-monero-env/action.yml, + # minus cross-compilation bits (mingw-w64, nsis) that we don't need here. + nativeBuildInputs = (with pkgs; [ + # C/C++ toolchain for monero-sys (CMake + monero-depends/make) + gcc + gnumake + cmake + autoconf + automake + libtool + pkg-config + binutils + ccache + gperf + lbzip2 + curl + git + python3 + + # Node for src-gui. The project pins `yarn@4.x` via `packageManager` in + # src-gui/package.json, so we let corepack (bundled with nodejs) fetch + # that exact version instead of using nixpkgs' yarn 1.x. + nodejs_22 + + # Cargo workspace helpers used by `just` recipes and the CI workflow. + just + typeshare + dprint + sqlx-cli + # `just tauri` runs `cargo tauri dev`, which needs the Rust tauri CLI + # on PATH (provides the `cargo-tauri` subcommand shim). The GitHub CI + # uses the yarn-based `@tauri-apps/cli` instead, so it doesn't need this. + cargo-tauri + ]) ++ [ moneroDependsToolchain ]; + + # Native libraries linked by src-tauri and its webkit-based webview. + buildInputs = tauriLinkLibs; + + # monero-sys build.rs picks up $CC/$CXX; be explicit so we don't accidentally + # pull in a host toolchain that isn't in $PATH under nix-shell. + CC = "${pkgs.gcc}/bin/gcc"; + CXX = "${pkgs.gcc}/bin/g++"; + + # WebKitGTK dlopens some of its plugins at runtime, so `tauri dev` + # needs them reachable via LD_LIBRARY_PATH in addition to being linked. + LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath tauriRuntimeLibs; + + shellHook = '' + # Rustup-managed toolchain lives in ~/.cargo/bin; nix-shell resets PATH + # for its own deps, so re-prepend it. rust-toolchain.toml pins the version. + export PATH="$HOME/.cargo/bin:$PATH" + + # Let corepack materialise the project-pinned yarn version into a user- + # writable dir (nodejs bin in /nix/store is read-only, so the default + # `corepack enable` location fails). + export COREPACK_HOME="$HOME/.cache/corepack" + export COREPACK_ENABLE_DOWNLOAD_PROMPT=0 + corepack_bin="$HOME/.cache/corepack/bin" + mkdir -p "$corepack_bin" + ${pkgs.nodejs_22}/bin/corepack enable --install-directory "$corepack_bin" + export PATH="$corepack_bin:$PATH" + + # GSettings/GIO schemas for GTK apps (otherwise Tauri dialogs warn/crash). + export XDG_DATA_DIRS="${pkgs.gsettings-desktop-schemas}/share/gsettings-schemas/${pkgs.gsettings-desktop-schemas.name}:${pkgs.gtk3}/share/gsettings-schemas/${pkgs.gtk3.name}:$XDG_DATA_DIRS" + ''; +} From 6d57c223b156a71ad7fe96cc183c525b06e9bb89 Mon Sep 17 00:00:00 2001 From: einliterflasche Date: Fri, 8 May 2026 13:46:29 +0200 Subject: [PATCH 2/4] build(nix-shell): fix tauri dev whitescreen and missing build-script libs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `just tauri-mainnet` couldn't get past the swap build script (libz.so.1 not found) and, once that was bypassed, the tauri webview rendered as a blank whitescreen with `EGL_BAD_PARAMETER. Aborting...` from WebKit. Two underlying issues: - cc-wrapper's add-flags.sh prepends `-rpath $out/lib` to NIX_LDFLAGS, but in nix-shell `$out` is a phantom path that never exists. Every binary cargo links here ends up with a dead RUNPATH, so dynamic deps (libgit2-sys → libz, webkitgtk → libgdk/libgtk/libstdc++) can't be resolved at runtime. Rewrite the rpath in shellHook to point at the link-time inputs. - WebKitGTK uses libglvnd for EGL/GLX dispatch, but nixpkgs' libglvnd has no vendor ICD installed. On NixOS the system populates `/run/opengl-driver/lib`; on non-NixOS hosts there's nothing to dispatch to. Point libglvnd at nixpkgs' mesa (which ships libEGL_mesa.so.0 + swrast_dri.so + the matching egl_vendor.d JSON) and force LIBGL_ALWAYS_SOFTWARE so we don't try to talk to the host NVIDIA/Mesa drivers (whose ABIs clash with the nix-built lib stack). This unblocks `cargo tauri dev` end-to-end with the CPU-side renderer. GPU-accelerated rendering on non-NixOS hosts (nixGL or equivalent) will follow in a separate change. Co-Authored-By: Claude Opus 4.7 (1M context) --- shell.nix | 58 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/shell.nix b/shell.nix index c16e3c3f8f..6ab7e757ed 100644 --- a/shell.nix +++ b/shell.nix @@ -21,10 +21,14 @@ let }; # Link-time deps for src-tauri and upstream Rust crates. These are found - # via pkg-config + nix-managed RPATH; do NOT add them to LD_LIBRARY_PATH - # because that overrides RPATH and can shadow binaries built against a - # newer openssl (e.g. curl's ngtcp2 module). - tauriLinkLibs = with pkgs; [ + # via pkg-config and the RPATH baked in by NIX_LDFLAGS (rewritten in + # shellHook below — see the comment there for why); we deliberately keep + # them off LD_LIBRARY_PATH so they can't shadow nix-built tools like curl + # whose ngtcp2 module is pinned to a specific openssl ABI. + # + # `stdenv.cc.cc.lib` is included so RUNPATH covers libstdc++.so.6, which + # the tauri binary pulls in via the C++ webkitgtk/cxx bindings. + tauriLinkLibs = (with pkgs; [ glib gtk3 gdk-pixbuf @@ -38,16 +42,28 @@ let libayatana-appindicator openssl zlib - ]; + ]) ++ [ pkgs.stdenv.cc.cc.lib ]; # Subset that WebKitGTK / GTK dlopen at runtime (tray icon, SVG pixbuf - # loaders, webview plugins). These must be reachable via LD_LIBRARY_PATH. + # loaders, webview plugins). dlopen of a bare soname only consults + # LD_LIBRARY_PATH and the system cache, not the calling binary's RUNPATH, + # so these have to be on LD_LIBRARY_PATH even though they're also linked. + # + # zlib is here as a safety net for cargo build-script binaries (e.g. + # the vergen-git2 -> libgit2-sys path used by swap, swap-asb, + # swap-orchestrator). The rpath rewrite in shellHook fixes their + # RUNPATH for fresh links, but build-script binaries linked before + # the fix went in still carry a dead RUNPATH and would fail to + # resolve libz when cargo re-runs them after a `rerun-if-changed` + # trigger (e.g. a new git commit). Keeping libz on LD_LIBRARY_PATH + # avoids forcing users to `cargo clean` after picking up shell.nix. tauriRuntimeLibs = with pkgs; [ webkitgtk_4_1 libsoup_3 librsvg libayatana-appindicator gdk-pixbuf + zlib ]; in pkgs.mkShell { @@ -99,7 +115,37 @@ pkgs.mkShell { # needs them reachable via LD_LIBRARY_PATH in addition to being linked. LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath tauriRuntimeLibs; + # WebKitGTK uses libglvnd (from nixpkgs) for EGL/GLX dispatch, but the + # nix-shipped libglvnd has no vendor ICD installed by default. On NixOS + # the system populates `/run/opengl-driver/lib`; on a non-NixOS host + # there's nothing for libglvnd to dispatch to, so `eglGetDisplay` returns + # EGL_NO_DISPLAY, WebKit prints `Could not create default EGL display: + # EGL_BAD_PARAMETER. Aborting...`, and the WebProcess crashes — leaving + # the tauri window as a blank whitescreen. Point libglvnd at nixpkgs' + # mesa (which ships `libEGL_mesa.so.0`, `swrast_dri.so` and the matching + # `egl_vendor.d` JSON) and force software rendering so we don't try to + # talk to the host's NVIDIA/Mesa drivers (whose ABIs would clash with + # the nix-built lib stack). + WEBKIT_DISABLE_DMABUF_RENDERER = "1"; + LIBGL_ALWAYS_SOFTWARE = "1"; + __EGL_VENDOR_LIBRARY_DIRS = "${pkgs.mesa}/share/glvnd/egl_vendor.d"; + LIBGL_DRIVERS_PATH = "${pkgs.mesa}/lib/dri"; + shellHook = '' + # cc-wrapper's add-flags.sh prepends `-rpath $out/lib` to NIX_LDFLAGS so + # mkDerivation builds get a working RUNPATH at install time. In a + # nix-shell, however, $out resolves to /outputs/out — a path that + # never exists — so every binary cargo links here (build scripts and + # the tauri app itself) ends up with a dead RUNPATH and can't load its + # dynamic deps at runtime. Rewrite the bogus rpath to point at the + # link-time inputs so RUNPATH actually resolves and we don't have to + # leak everything onto LD_LIBRARY_PATH. + if [ -n "$out" ] && [[ "$NIX_LDFLAGS" == *"-rpath $out/lib"* ]]; then + _rpath_real=${pkgs.lib.makeLibraryPath tauriLinkLibs} + export NIX_LDFLAGS="''${NIX_LDFLAGS//-rpath $out\/lib/-rpath $_rpath_real}" + unset _rpath_real + fi + # Rustup-managed toolchain lives in ~/.cargo/bin; nix-shell resets PATH # for its own deps, so re-prepend it. rust-toolchain.toml pins the version. export PATH="$HOME/.cargo/bin:$PATH" From 3bdfd562c326776cac38ab0701069dced79a1f20 Mon Sep 17 00:00:00 2001 From: einliterflasche Date: Fri, 8 May 2026 13:53:13 +0200 Subject: [PATCH 3/4] build(nix-shell): use host NVIDIA driver for tauri webview when available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Software rendering (the previous fix) is functional but caps the webview at a few fps on a modern GPU. Detect the proprietary NVIDIA driver on the host and surface its libnvidia-*/libEGL_nvidia/libGLX_nvidia files via a focused symlink directory on LD_LIBRARY_PATH so nix's libglvnd can dispatch into the host's driver and render on the GPU. We can't put /usr/lib64 on LD_LIBRARY_PATH directly — that would shadow nix's libstdc++/libc and segfault the process — so the symlink dir contains only the libnvidia/libEGL_nvidia/libGLX_nvidia files, and the rest of /usr/lib64 stays out of the search path. The NVIDIA libs themselves only depend on glibc + each other, and they pick up nix's glibc-2.40 cleanly. When NVIDIA isn't present we keep the nixpkgs mesa software rasteriser fallback so non-NVIDIA hosts still launch (just slower). Co-Authored-By: Claude Opus 4.7 (1M context) --- shell.nix | 54 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/shell.nix b/shell.nix index 6ab7e757ed..5374345b52 100644 --- a/shell.nix +++ b/shell.nix @@ -115,21 +115,13 @@ pkgs.mkShell { # needs them reachable via LD_LIBRARY_PATH in addition to being linked. LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath tauriRuntimeLibs; - # WebKitGTK uses libglvnd (from nixpkgs) for EGL/GLX dispatch, but the - # nix-shipped libglvnd has no vendor ICD installed by default. On NixOS - # the system populates `/run/opengl-driver/lib`; on a non-NixOS host - # there's nothing for libglvnd to dispatch to, so `eglGetDisplay` returns - # EGL_NO_DISPLAY, WebKit prints `Could not create default EGL display: - # EGL_BAD_PARAMETER. Aborting...`, and the WebProcess crashes — leaving - # the tauri window as a blank whitescreen. Point libglvnd at nixpkgs' - # mesa (which ships `libEGL_mesa.so.0`, `swrast_dri.so` and the matching - # `egl_vendor.d` JSON) and force software rendering so we don't try to - # talk to the host's NVIDIA/Mesa drivers (whose ABIs would clash with - # the nix-built lib stack). + # WebKit's DMA-BUF renderer needs an EGL backend that can negotiate + # buffer sharing with the compositor; the host driver path below covers + # the EGL initialisation, but DMA-BUF still tends to fail on non-NixOS + # hosts (mismatch between the nix-built webkitgtk and the host's + # wayland/drm stack). Disable it so WebKit falls back to a glReadPixels- + # style upload that works with any GL backend. WEBKIT_DISABLE_DMABUF_RENDERER = "1"; - LIBGL_ALWAYS_SOFTWARE = "1"; - __EGL_VENDOR_LIBRARY_DIRS = "${pkgs.mesa}/share/glvnd/egl_vendor.d"; - LIBGL_DRIVERS_PATH = "${pkgs.mesa}/lib/dri"; shellHook = '' # cc-wrapper's add-flags.sh prepends `-rpath $out/lib` to NIX_LDFLAGS so @@ -146,6 +138,40 @@ pkgs.mkShell { unset _rpath_real fi + # WebKitGTK uses nixpkgs' libglvnd for EGL/GLX dispatch, but nixpkgs + # ships libglvnd without any vendor ICD installed — on NixOS the system + # populates /run/opengl-driver/lib, on a non-NixOS host there's nothing + # for libglvnd to dispatch to. Result: WebKit aborts with `Could not + # create default EGL display: EGL_BAD_PARAMETER` and the tauri webview + # renders as a blank whitescreen. + # + # If the host has the proprietary NVIDIA driver, surface its + # libnvidia-*/libEGL_nvidia/libGLX_nvidia files via a focused symlink + # dir on LD_LIBRARY_PATH (we can NOT put /usr/lib64 on LD_LIBRARY_PATH + # directly — that shadows nix's libstdc++/libc and segfaults the + # process). Combined with the host's /usr/share/glvnd/egl_vendor.d/ + # JSON, nix's libglvnd dispatches into the host driver and gets real + # GPU rendering. + # + # Otherwise fall back to nixpkgs' mesa software rasteriser. Slow but + # works without any host driver and without ABI mixing. + if [ -e /usr/lib64/libEGL_nvidia.so.0 ] && [ -d /usr/share/glvnd/egl_vendor.d ]; then + _nv_dir="''${XDG_RUNTIME_DIR:-/tmp}/eigenwallet-nvidia-libs" + rm -rf "$_nv_dir" + mkdir -p "$_nv_dir" + for _f in /usr/lib64/libnvidia-*.so.* /usr/lib64/libEGL_nvidia.so.* /usr/lib64/libGLX_nvidia.so.*; do + [ -e "$_f" ] && ln -s "$_f" "$_nv_dir/" + done + export LD_LIBRARY_PATH="''${LD_LIBRARY_PATH}:$_nv_dir" + export __EGL_VENDOR_LIBRARY_DIRS=/usr/share/glvnd/egl_vendor.d + export __GLX_VENDOR_LIBRARY_NAME=nvidia + unset _nv_dir _f + else + export __EGL_VENDOR_LIBRARY_DIRS=${pkgs.mesa}/share/glvnd/egl_vendor.d + export LIBGL_DRIVERS_PATH=${pkgs.mesa}/lib/dri + export LIBGL_ALWAYS_SOFTWARE=1 + fi + # Rustup-managed toolchain lives in ~/.cargo/bin; nix-shell resets PATH # for its own deps, so re-prepend it. rust-toolchain.toml pins the version. export PATH="$HOME/.cargo/bin:$PATH" From cbabd6c9dadd12d3aee20e293ac634db5cc10f65 Mon Sep 17 00:00:00 2001 From: einliterflasche Date: Fri, 8 May 2026 14:38:11 +0200 Subject: [PATCH 4/4] build(nix-shell): use nixGL for NVIDIA GPU rendering on non-NixOS hosts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous attempt symlinked the host's NVIDIA libs from /usr/lib64 into a focused dir on LD_LIBRARY_PATH. That got nix's libglvnd to load the libs, but glXChooseFBConfig still returned NULL ("No available configurations for the given pixel format"), GTK disabled hardware acceleration, and WebKit fell back to CPU rasterisation — capping the GUI at single-digit fps even though the NVIDIA libs were resident. nixGL builds nix-managed copies of the host's NVIDIA user-space driver (matching the running kernel module's version) and a wrapper that points libglvnd at them. Sourcing the wrapper's env-var setup into the nix-shell at entry gives the WebProcess a working EGL vendor without needing to wrap every cargo invocation. Combined with GDK_BACKEND=x11 (NVIDIA + native Wayland + nix's webkitgtk hits a Wayland EPROTO during DMA-BUF setup; XWayland sidesteps that path), WebKit now renders on the GPU end-to-end: - nvidia-smi shows WebKitWebProcess holding ~200 MiB of GPU memory - WebProcess CPU drops from ~98% to ~40% under the same workload - GPU utilisation jumps from idle to 40-50% `config.allowUnfree = true` is required on the nixpkgs import for the NVIDIA runfile fetch. The driver version defaults to 580.142 (matches the user's current kernel module) and is overridable via `--argstr nvidiaVersion `. The shellHook compares the pin against `/proc/driver/nvidia/version` at entry and warns on mismatch so a kernel-driver upgrade produces a clear diagnostic rather than silent GPU breakage. Hosts without the NVIDIA driver continue to use the nixpkgs mesa software rasteriser fallback. Co-Authored-By: Claude Opus 4.7 (1M context) --- shell.nix | 87 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 35 deletions(-) diff --git a/shell.nix b/shell.nix index 5374345b52..6a8e2a024b 100644 --- a/shell.nix +++ b/shell.nix @@ -1,6 +1,14 @@ { pkgs ? import (builtins.fetchTarball { url = "https://github.com/NixOS/nixpkgs/archive/refs/heads/nixos-25.05.tar.gz"; - }) { } + # config.allowUnfree is required for the proprietary NVIDIA user-space + # driver that nixGLNvidia (below) builds against; falls back to mesa + # software rendering on hosts without the NVIDIA driver. + }) { config.allowUnfree = true; } +, # Override to match `cat /proc/driver/nvidia/version` when your host's + # NVIDIA kernel module differs from the default. nixpkgs fixed-output- + # fetches the matching user-space runfile, so a wrong value produces a + # clear hash-mismatch error rather than silent corruption. + nvidiaVersion ? "580.142" }: let @@ -20,6 +28,22 @@ let [ "ar" "ranlib" "nm" "strip" "ld" "as" "objcopy" "objdump" "readelf" ]; }; + # nixGLNvidia is a thin wrapper script that sets `LD_LIBRARY_PATH` and + # `__EGL_VENDOR_LIBRARY_FILENAMES` to nix-managed copies of the host's + # proprietary NVIDIA driver, so nix-built libglvnd can dispatch into a + # working EGL/GLX vendor. We don't invoke the wrapper directly — its + # `export` statements are sourced into the shell below so `cargo tauri + # dev` picks up the right env without further wrapping. + # + # Without this, nix's libglvnd has no vendor ICD installed (NixOS + # populates /run/opengl-driver/lib; non-NixOS hosts have nothing), so + # WebKit's WebProcess can't initialise EGL and either aborts with + # `EGL_BAD_PARAMETER` or silently falls back to CPU rasterisation, + # capping the GUI at single-digit fps even on a discrete GPU. + nixGLNvidia = (import (builtins.fetchTarball { + url = "https://github.com/nix-community/nixGL/archive/refs/heads/main.tar.gz"; + }) { inherit pkgs nvidiaVersion; }).nixGLNvidia; + # Link-time deps for src-tauri and upstream Rust crates. These are found # via pkg-config and the RPATH baked in by NIX_LDFLAGS (rewritten in # shellHook below — see the comment there for why); we deliberately keep @@ -115,14 +139,6 @@ pkgs.mkShell { # needs them reachable via LD_LIBRARY_PATH in addition to being linked. LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath tauriRuntimeLibs; - # WebKit's DMA-BUF renderer needs an EGL backend that can negotiate - # buffer sharing with the compositor; the host driver path below covers - # the EGL initialisation, but DMA-BUF still tends to fail on non-NixOS - # hosts (mismatch between the nix-built webkitgtk and the host's - # wayland/drm stack). Disable it so WebKit falls back to a glReadPixels- - # style upload that works with any GL backend. - WEBKIT_DISABLE_DMABUF_RENDERER = "1"; - shellHook = '' # cc-wrapper's add-flags.sh prepends `-rpath $out/lib` to NIX_LDFLAGS so # mkDerivation builds get a working RUNPATH at install time. In a @@ -138,38 +154,39 @@ pkgs.mkShell { unset _rpath_real fi - # WebKitGTK uses nixpkgs' libglvnd for EGL/GLX dispatch, but nixpkgs - # ships libglvnd without any vendor ICD installed — on NixOS the system - # populates /run/opengl-driver/lib, on a non-NixOS host there's nothing - # for libglvnd to dispatch to. Result: WebKit aborts with `Could not - # create default EGL display: EGL_BAD_PARAMETER` and the tauri webview - # renders as a blank whitescreen. + # GPU rendering setup. WebKitGTK uses libglvnd for EGL/GLX dispatch; + # nix's libglvnd has no vendor ICD installed, so on a non-NixOS host + # WebKit can't reach the GPU. Two paths: # - # If the host has the proprietary NVIDIA driver, surface its - # libnvidia-*/libEGL_nvidia/libGLX_nvidia files via a focused symlink - # dir on LD_LIBRARY_PATH (we can NOT put /usr/lib64 on LD_LIBRARY_PATH - # directly — that shadows nix's libstdc++/libc and segfaults the - # process). Combined with the host's /usr/share/glvnd/egl_vendor.d/ - # JSON, nix's libglvnd dispatches into the host driver and gets real - # GPU rendering. + # - host has the proprietary NVIDIA driver: source the env vars from + # a pre-built nixGLNvidia wrapper, which points libglvnd at nix- + # managed copies of the host's NVIDIA libs (avoids ABI-mixing + # /usr/lib64 with the nix lib stack). We also force GDK_BACKEND=x11 + # because NVIDIA + native Wayland + nix's webkitgtk hits a Wayland + # EPROTO during DMA-BUF setup; XWayland sidesteps that path. # - # Otherwise fall back to nixpkgs' mesa software rasteriser. Slow but - # works without any host driver and without ABI mixing. - if [ -e /usr/lib64/libEGL_nvidia.so.0 ] && [ -d /usr/share/glvnd/egl_vendor.d ]; then - _nv_dir="''${XDG_RUNTIME_DIR:-/tmp}/eigenwallet-nvidia-libs" - rm -rf "$_nv_dir" - mkdir -p "$_nv_dir" - for _f in /usr/lib64/libnvidia-*.so.* /usr/lib64/libEGL_nvidia.so.* /usr/lib64/libGLX_nvidia.so.*; do - [ -e "$_f" ] && ln -s "$_f" "$_nv_dir/" - done - export LD_LIBRARY_PATH="''${LD_LIBRARY_PATH}:$_nv_dir" - export __EGL_VENDOR_LIBRARY_DIRS=/usr/share/glvnd/egl_vendor.d - export __GLX_VENDOR_LIBRARY_NAME=nvidia - unset _nv_dir _f + # - no NVIDIA: fall back to nixpkgs' mesa software rasteriser. Slow + # (single-digit fps) but works on any host without ABI mixing, and + # WEBKIT_DISABLE_DMABUF_RENDERER=1 keeps the WebProcess from + # trying a hardware path it can't satisfy. + if [ -e /proc/driver/nvidia/version ]; then + _host_nv=$(awk '/Module/ { for(i=1;i<=NF;i++) if($i ~ /^[0-9]+\.[0-9]+/) { print $i; exit } }' /proc/driver/nvidia/version 2>/dev/null) + if [ -n "$_host_nv" ] && [ "$_host_nv" != "${nvidiaVersion}" ]; then + echo "[shell.nix] WARNING: nvidia kernel module is $_host_nv but shell.nix is pinned to ${nvidiaVersion}." >&2 + echo "[shell.nix] GPU rendering may break — pass --argstr nvidiaVersion $_host_nv or update shell.nix." >&2 + fi + unset _host_nv + + # Source the nixGLNvidia wrapper's env-var setup. The wrapper ends + # in `exec "$@"`; strip that line so sourcing doesn't try to exec + # an empty argv. Bash arrays (NVIDIA_JSON*=) are evaluated too. + eval "$(${pkgs.gnused}/bin/sed '/^[[:space:]]*exec /d' ${nixGLNvidia}/bin/nixGLNvidia-${nvidiaVersion})" + export GDK_BACKEND=x11 else export __EGL_VENDOR_LIBRARY_DIRS=${pkgs.mesa}/share/glvnd/egl_vendor.d export LIBGL_DRIVERS_PATH=${pkgs.mesa}/lib/dri export LIBGL_ALWAYS_SOFTWARE=1 + export WEBKIT_DISABLE_DMABUF_RENDERER=1 fi # Rustup-managed toolchain lives in ~/.cargo/bin; nix-shell resets PATH