Files
Aleksandr Bogomiakov 8a6216bccb Expose tray runtime libraries in the Nix development shell
The development shell inherited build dependencies but Cargo-built tray
binaries lack the installed package's wrapper. AppIndicator was present in
the store yet its dlopen lookup failed because the runtime library path was
missing. The same problem affected dynamically loaded graphics libraries.

Expose the package's existing trayRuntimeLibs through passthru and reuse that
list in mkShell packages and its LD_LIBRARY_PATH hook. Include the existing
NixOS OpenGL driver path and preserve any caller-supplied library paths.
The development shell and installed tray now share one dependency list.
Document direct execution of Cargo-built tray binaries inside nix develop.
No agent, protocol, package version or system configuration changes.

Validation on Linux:
- Reproduced the missing AppIndicator dlopen failure before the change.
- Loaded libayatana-appindicator3.so.1, libxkbcommon-x11.so.0, libEGL.so.1,
  libGL.so.1 and libwayland-client.so.0 inside the updated shell.
- Verified AppIndicator still loads with an inherited LD_LIBRARY_PATH and
  that the existing value is preserved. The first probe used an older host
  Python with an incompatible glibc; probes using Python from the pinned
  nixpkgs input passed.
- Evaluated the x86_64-linux CLI package and shared runtime dependency list,
  and the aarch64-linux development shell; no aarch64 execution claimed.
- nixfmt --check flake.nix nix/package.nix
- cargo fmt --all -- --check
- cargo clippy --locked --workspace --all-targets -- -D warnings
- cargo test --locked --workspace --all-targets: 566 passed, 3 ignored
Cargo checks ran through nix develop, with TSUNAGI_CONTROL_SOCKET unset for
Clippy and tests. Existing agent and tray processes were not restarted.
2026-10-21 17:05:25 +01:00

102 lines
2.2 KiB
Nix

{
withTray ? true,
lib,
rustPlatform,
pkg-config,
copyDesktopItems,
wrapGAppsHook3,
gtk3,
libayatana-appindicator,
libglvnd,
libxkbcommon,
vulkan-loader,
wayland,
xdotool,
libx11,
libxcursor,
libxi,
libxrandr,
}:
let
# The tray is an egui app that loads graphics, windowing and appindicator
# libraries at run time, so they have to be put on its library path by hand.
trayRuntimeLibs = [
libayatana-appindicator
libglvnd
libxkbcommon
vulkan-loader
wayland
libx11
libxcursor
libxi
libxrandr
];
in
rustPlatform.buildRustPackage {
pname = if withTray then "tsunagi" else "tsunagi-cli";
version = "0.1.0";
src = lib.cleanSource ../.;
cargoLock.lockFile = ../Cargo.lock;
cargoBuildFlags = [
"--bin"
"tsng"
]
++ lib.optionals withTray [
"--bin"
"tsunagi-tray"
];
# The suite opens real sockets and interfaces; it runs in CI instead.
doCheck = false;
nativeBuildInputs = [
pkg-config
]
++ lib.optionals withTray [
copyDesktopItems
wrapGAppsHook3
];
buildInputs = lib.optionals withTray [
gtk3
libayatana-appindicator
xdotool
];
dontWrapGApps = true;
# The development shell runs unwrapped Cargo binaries and needs the same
# dynamically loaded libraries as the installed tray wrapper.
passthru = { inherit trayRuntimeLibs; };
postInstall = ''
install -Dm644 dist/linux/50-tsunagi-resolved.rules \
"$out/share/doc/tsunagi/50-tsunagi-resolved.rules"
''
+ lib.optionalString withTray ''
install -Dm644 dist/linux/tsunagi.svg \
"$out/share/icons/hicolor/scalable/apps/tsunagi.svg"
install -Dm644 dist/linux/tsunagi-tray.desktop \
"$out/share/applications/tsunagi-tray.desktop"
'';
postFixup = lib.optionalString withTray ''
wrapProgram "$out/bin/tsunagi-tray" \
"''${gappsWrapperArgs[@]}" \
--prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath trayRuntimeLibs}:/run/opengl-driver/lib
'';
meta = {
description = "Serverless mesh VPN: join a network with a name and a secret";
homepage = "https://github.com/house-of-vanity/tsunagi";
license = lib.licenses.wtfpl;
mainProgram = "tsng";
platforms = [
"x86_64-linux"
"aarch64-linux"
];
};
}