#!/usr/bin/env bash # AppRun entry point for the Lutris AppImage. # # Two responsibilities: # 1. Source linuxdeploy-plugin-gtk's hook so GI_TYPELIB_PATH, GDK_PIXBUF_*, # XDG_DATA_DIRS, etc. point inside the AppDir. # 2. Launch bin/lutris with the bundled Python interpreter. # # Lutris is intentionally NOT sandboxed: it must call host binaries (xrandr, # 7z, fuser, wine, the user's installed runners), read the user's $HOME, # and access mounted drives. We deliberately leave PATH and PYTHONPATH # alone so host tools and host Python (used by host subprocesses like # umu-run) work as they do outside the AppImage. The build script # installs Lutris's package files via --install-layout=deb so the # bundled Python finds them via its standard dist-packages search, # without us needing to advertise an AppDir path on PYTHONPATH. set -e HERE="$(dirname "$(readlink -f "${0}")")" # linuxdeploy-plugin-gtk writes its environment setup into apprun-hooks/. # Source every hook it dropped so we inherit the GTK/Pixbuf/typelib paths. if [ -d "$HERE/apprun-hooks" ]; then for hook in "$HERE"/apprun-hooks/*.sh; do # shellcheck disable=SC1090 [ -r "$hook" ] && . "$hook" done fi export APPDIR="$HERE" # WebKit2 4.1 spawns helper processes (WebKitNetworkProcess, # WebKitWebProcess) from a compile-time path baked into # libwebkit2gtk-4.1.so.0. WEBKIT_EXEC_PATH does not exist in this # build, so the build script byte-patched the hardcoded path inside # the .so to /tmp/.lutris-appimage.dir/webkit2gtk-4.1 (same length as # the original). Symlink that location to our bundled helpers before # launching. # # Disable WebKit's bubblewrap sandbox: it creates a fresh mount # namespace with only paths WebKit's own policy bind-mounts, and the # AppImage's FUSE mount at /tmp/.mount_LutrisXXX is not one of them. # The helpers execvp inside the sandbox and can't reach either the # symlink target or the bundled libs. Lutris already runs with full # user-home access and spawns Wine binaries — a WebKit sandbox layered # on top adds negligible additional isolation, and disabling it is # standard practice for AppImage-packaged WebKitGTK apps. if [ -d "$HERE/usr/lib/webkit2gtk-4.1" ]; then mkdir -p /tmp/.lutris-appimage.dir ln -snf "$HERE/usr/lib/webkit2gtk-4.1" /tmp/.lutris-appimage.dir/webkit2gtk-4.1 export WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS=1 fi # GLib's GIO looks for extension modules (TLS backends, proxy resolvers, # etc.) at a compile-time libdir. Point it at our bundled copy explicitly; # otherwise WebKit reports "TLS is not available" and any HTTPS login flow # fails at the first request. This is silently masked on Debian/Ubuntu # hosts because the compile-time fallback path exists there, but breaks # on Fedora/Arch/openSUSE where it doesn't. if [ -d "$HERE/usr/lib/gio/modules" ]; then export GIO_MODULE_DIR="$HERE/usr/lib/gio/modules" fi # Intentionally do NOT export LD_LIBRARY_PATH. linuxdeploy already set # RPATH=$ORIGIN/.. on every bundled binary, so they find their sibling libs # without an env override. Exporting LD_LIBRARY_PATH here would leak into # subprocesses — and Lutris launches host binaries constantly (xrandr, 7z, # fuser, /usr/bin/flatpak, wine, etc.). Forcing them to load our older # bundled libssl/libcrypto/libstdc++ breaks any host tool whose own deps # were built against newer symbols. The cost of this discipline is that # anything we copied into the AppDir manually (PyGObject's _gi.so, # python3-dbus' bindings) must have its RPATH patched by the build script, # since linuxdeploy only patches files it deploys itself. unset LD_LIBRARY_PATH # Python: find the bundled interpreter and site-packages. We accept any # python3.X under usr/bin so this script doesn't need to be rev'd when the # build image's Python minor version changes. PYTHON_BIN="" for cand in "$HERE"/usr/bin/python3.* "$HERE"/usr/bin/python3; do if [ -x "$cand" ] && [ ! -L "$cand" ]; then PYTHON_BIN="$cand" break fi done if [ -z "$PYTHON_BIN" ]; then # Fallback: host python3. The AppImage is less portable this way, but # at least it boots so the user sees a real error rather than nothing. PYTHON_BIN="$(command -v python3 || true)" fi if [ -z "$PYTHON_BIN" ]; then echo "Lutris AppImage: no python3 interpreter found in AppDir or host" >&2 exit 1 fi # bin/lutris strips /home paths from sys.path unless this is set, which # would also drop the AppDir paths Python auto-discovered when extracted # AppImages live under /home (e.g. ~/Applications). export LUTRIS_ALLOW_LOCAL_PYTHON_PACKAGES=1 exec "$PYTHON_BIN" "$HERE/usr/bin/lutris" "$@"