fix(linux): make AppImage work on Mesa 25+ / GLib 2.88 distros#1567
Open
wpfleger96 wants to merge 2 commits into
Open
fix(linux): make AppImage work on Mesa 25+ / GLib 2.88 distros#1567wpfleger96 wants to merge 2 commits into
wpfleger96 wants to merge 2 commits into
Conversation
19eb8af to
54a8a5e
Compare
Vanilla tauri-bundler (no bundle.linux config) ships libwayland-client, libglib/gio/gobject, all libgst*.so*, and other infra libs into the AppImage. On newer distros (Ubuntu 26.04, Mesa 25+), the bundled versions clash with the system: libwayland-client 1.22 causes eglGetDisplay to return EGL_BAD_PARAMETER under Wayland (WebKitWebProcess aborts before rendering), and the empty bundled gstreamer-1.0 dir disables GStreamer plugin discovery. No tauri.conf.json knob exists to remove or symlink bundled libs; the bundle.linux.appimage surface only exposes bundleMediaFramework/files/bundleXdgOpen. Add desktop/scripts/fix-appimage.sh to post-process the AppImage: extracts it, removes the conflicting infra libs, symlinks the system GStreamer plugin dir, repacks with appimagetool, and re-signs if TAURI_SIGNING_PRIVATE_KEY is present (handling both .AppImage.sig and .AppImage.tar.gz.sig updater artifact formats). Wire it into release.yml after the tauri build step, and switch the job to container: ubuntu:22.04 so linuxdeploy links against the oldest-supported GLIBC (per tauri docs; avoids the ubuntu-22.04 runner deprecation starting Sept 2026).
54a8a5e to
7f435ff
Compare
Fail loudly instead of silently shipping an unfixed artifact when the bundler layout changes, and refuse unverified appimagetool binaries on new arches. Keep the signing password off argv (the signer reads it from the env). Pin the remaining mutable release-job inputs: container image digest, gh keyring hash, and the AppImage type2 runtime, which appimagetool otherwise fetches from its mutable continuous tag at repack time. Document the AppImage host floor in RELEASING.md and fix the stale Linux auto-update note.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The 0.3.45 AppImage silently fails to launch on Ubuntu 26.04 — and it should be shipping Mesa 25+ / GLib 2.88 — the window never appears. I debugged it down to three interlocking problems that all stem from the same root cause: vanilla tauri-bundler over-bundles Linux infra libs that conflict with what's on the host.
EGL crash. linuxdeploy-plugin-gtk pulls in
libwayland-client.so.0(version 1.22) alongside the app. On Mesa 25+ that bundled version gets loaded at runtime, andeglGetDisplayreturnsEGL_BAD_PARAMETERunder a Wayland session.WebKitWebProcesstreats that as fatal and aborts before the window ever renders. Verified on this machine —"Could not create default EGL display: EGL_BAD_PARAMETER. Aborting..."appears in stderr every time.GStreamer crash. The bundled
libgst*.so*(10 core libs) are present, butAppRununconditionally setsGST_PLUGIN_SYSTEM_PATH_1_0to$APPDIR/usr/lib/gstreamer-1.0, a directory the bundler never populates whenbundleMediaFrameworkis false (the default). With no plugins,appsinkis missing, WebKit connects signals on a null element, and the render process dies with GLib-GObject-CRITICAL errors. As a side effect the broken run poisons~/.cache/gstreamer-1.0/registry.x86_64.bin— the registry gets rebuilt as an empty 76-byte stub on the next run.WebKit helper mismatch (latent). The bundled WebKit 2.44 helpers have
RUNPATH=$ORIGINonly, so any launch path that bypasses AppRun'schdircauses the dynamic linker to load system WebKit 2.52 helpers instead, producing IPC mismatches and eventualSIGBUSinWebKitNetworkProcess.There's no
tauri.conf.jsonknob that fixes this.bundle.linux.appimageonly exposesbundleMediaFramework,files, andbundleXdgOpen.filesis a copy-only directive — it can't remove or symlink bundled libs — and nothing changed through tauri 2.11.5. Upstream issue: tauri-apps/tauri#15665.What this PR does.
desktop/scripts/fix-appimage.shtakes a built.AppImage, extracts it, removes the conflicting libs (libwayland-*,libglib/gio/gobject/gmodule-2.0,libmount/blkid/selinux/pcre2-8, alllibgst*.so*,libzstd/elf/ffi), symlinks/usr/lib/x86_64-linux-gnu/gstreamer-1.0(or the aarch64 equivalent) into the bundle'susr/lib/, repacks withappimagetool, and re-signs ifTAURI_SIGNING_PRIVATE_KEYis set — handling both.AppImage.sigand legacy.AppImage.tar.gz.sigupdater artifact formats so the in-app updater keeps working after the repack. The script fails loudly if the libs it expects to strip aren't where the bundler put them, so a future tauri/linuxdeploy upgrade that changes the bundled lib set breaks the release job instead of silently shipping an unfixed artifact. Signing relies on theTAURI_SIGNING_*env vars alone (same as the macOS jobs) — the password never appears on argv.The
release-linuxjob now runs inside acontainer: ubuntu:22.04image (digest-pinned, like the workflow's SHA-pinned actions; Renovate keeps both fresh) rather than directly on theubuntu-latestrunner. Building against the oldest-supported base is the approach recommended in the tauri docs for broad GLIBC compatibility, and theubuntu-22.04runner image hits deprecation in September 2026 anyway — using a container image onubuntu-latestis the cleaner long-term path. The job setsAPPIMAGE_EXTRACT_AND_RUN: "1"at the job level becauselinuxdeployandappimagetoolare themselves AppImages and containers lack FUSE. Everything the job downloads is pinned and integrity-checked:appimagetool1.9.1 by SHA256 (hard fail on any arch without a recorded hash), the GitHub CLI apt keyring by SHA256, and the AppImage type2 runtime from the immutable20251108release — without that last pin,appimagetoolfetches the runtime (the first code end users execute) from its mutablecontinuoustag at repack time.The tradeoff worth calling out: removing these libs means the AppImage now relies on the host's Wayland, GStreamer, and graphics stack. In practice that means Ubuntu 22.04+ (GLib ≥ 2.72) — which was already the practical floor, since older distros don't ship webkit2gtk-4.1 at all. RELEASING.md documents this host floor and the post-processing step, and corrects a stale note that claimed Linux users don't receive auto-updates (the updater manifest covers all four platform keys).
Release CI only runs on
block/buzz, so this was validated two ways. First, by post-processing the released 0.3.45 artifact directly on Ubuntu 26.04: the broken AppImage reproduces theEGL_BAD_PARAMETERabort every time, and the fixed copy starts cleanly with bothWebKitNetworkProcessandWebKitWebProcessstaying alive past 20 seconds and no EGL or GStreamer errors in stderr. Second, by exercising the full pipeline inside anubuntu:22.04container against the same released artifact: pinned tool + runtime downloads verify, extract → strip → symlink → repack succeeds, the repacked bundle contains none of the denylisted libs, and the layout guard fails loudly when pointed at an already-stripped AppImage.