#!/usr/bin/env sh # Devbox installs library packages as their -dev outputs, which carry no # shared objects; the outs they reference do. Put the GUI stack's real lib # dirs on LD_LIBRARY_PATH — wayland, xkbcommon, EGL and vulkan are dlopened # at runtime, so neither rpath nor a DT_NEEDED scan can cover them. Only # matching package names are picked up: a blanket list would drag glibc and # friends onto the path for every process in the shell. set -e if [ -z "$DEVBOX_PACKAGES_DIR" ]; then return 0 2>/dev/null || exit 0 fi MANIFEST="$DEVBOX_PACKAGES_DIR/manifest.json" [ -f "$MANIFEST" ] || return 0 2>/dev/null || exit 0 libs=$(python3 - "$MANIFEST" <<'EOF' import json, os, subprocess, sys wanted = ("wayland", "libxkbcommon", "libglvnd", "vulkan-loader", "mesa") manifest = json.load(open(sys.argv[1])) seen, dirs = set(), [] paths = [ path for name, el in manifest["elements"].items() if any(w in name for w in wanted) for path in el.get("storePaths", []) ] for path in paths: candidates = [path] try: candidates += subprocess.run( ["nix-store", "-q", "--references", path], capture_output=True, text=True, ).stdout.split() except OSError: pass for cand in candidates: lib = os.path.join(cand, "lib") base = os.path.basename(cand) if lib in seen or not os.path.isdir(lib): continue if not any(w in base for w in wanted): continue if any(name.endswith(".so") or ".so." in name for name in os.listdir(lib)): seen.add(lib) dirs.append(lib) print(":".join(dirs)) EOF ) export LD_LIBRARY_PATH="${libs}:${DEVBOX_PACKAGES_DIR}/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"