feat: portable AppImage build (bundled Qt6/KF6 runtime)#30
Closed
hikaps wants to merge 2 commits into
Closed
Conversation
Add a portable AppImage distribution: the GUI is bundled with its Qt6/KF6 runtime libraries via linuxdeploy + the Qt plugin, so it runs on current x86_64 desktops (glibc >= 2.39 baseline) without system Qt6/KF6. The privileged helper cannot run from the AppImage mount, so it is carried inside and installed on demand via a custom AppRun subcommand: ./CouchPlay-x86_64.AppImage install-helper which extracts the helper + installer and runs install-helper.sh install with sudo, landing the helper in system paths like the tarball. The helper then uses system Qt6/Polkit (missing libs reported by existing dep checks). - scripts/AppRun: GUI launch + install-helper subcommand - scripts/build-appimage.sh: build + linuxdeploy + appimagetool - .github/workflows/appimage.yml: fedora:40, tag + workflow_dispatch - README.md: AppImage install section Built on fedora:40 (glibc 2.39) for broad compat. Needs a workflow_dispatch run to validate the actual bundle (could not build a full KDE app locally). Refs #28
hikaps
added a commit
that referenced
this pull request
Jun 29, 2026
The release tarball's couchplay-helper is dynamically linked against system Qt6/Polkit/PipeWire but bundles none, so on minimal distros (e.g. Arch) it fails to start — the opaque exit / ERRNO 2 from #28. Bundle the helper's non-glibc runtime libs into lib/couchplay with a $ORIGIN-relative RPATH via patchelf: - scripts/bundle-libs.sh: ldd-gather deps (excluding glibc/ld-linux), copy, patchelf --set-rpath $ORIGIN/../lib/couchplay - release.yml: add patchelf, run bundle-libs.sh in the Package step - install-helper.sh: install/uninstall lib/couchplay to $PREFIX/lib/couchplay The helper now starts with zero system Qt6. glibc/ld-linux stay system-provided, so the binary still has the build container's glibc floor. The GUI still needs system Qt6 — a portable GUI is the AppImage's job (#30). Refs #28
The install documentation — including the AppImage section — is consolidated into PR #29 so the two PRs cannot conflict on README. This PR is now build-only (scripts + workflow).
hikaps
added a commit
that referenced
this pull request
Jun 29, 2026
The release tarball's couchplay-helper is dynamically linked against system Qt6/Polkit/PipeWire but bundles none, so on minimal distros (e.g. Arch) it fails to start — the opaque exit / ERRNO 2 from #28. Bundle the helper's non-glibc runtime libs into lib/couchplay with a $ORIGIN-relative RPATH via patchelf: - scripts/bundle-libs.sh: ldd-gather deps (excluding glibc/ld-linux), copy, patchelf --set-rpath $ORIGIN/../lib/couchplay - release.yml: add patchelf, run bundle-libs.sh in the Package step - install-helper.sh: install/uninstall lib/couchplay to $PREFIX/lib/couchplay The helper now starts with zero system Qt6. glibc/ld-linux stay system-provided, so the binary still has the build container's glibc floor. The GUI still needs system Qt6 — a portable GUI is the AppImage's job (#30). Refs #28
hikaps
added a commit
that referenced
this pull request
Jun 29, 2026
#28) (#29) * fix(install): robust D-Bus reload + correct Flatpak helper export path Resolve two install failures reported in #28: 1. couchplay-helper.service failed to start (Type=dbus unit exited 1). install-helper.sh masked D-Bus config-reload failures with || true, so the helper's ownership policy was never loaded and it could not register its service name. reload_dbus() now retries via SIGHUP on the pid file, failures are surfaced (not masked), and a failed start dumps the last 30 journalctl lines. 2. Flatpak export wrote to the sandbox home (~/.var/app/...) while the README/host command looked in ~/.local/share/couchplay, so the host-side install found nothing. The manifest now grants --filesystem=home and export resolves the real host home from /etc/passwd. README adds an older-build fallback path. Refs #28 * fix(install): correct Flatpak export path + detect missing runtime libs Follow-up to the #28 install fixes based on reporter feedback: - Flatpak export was still wrong: writing to $HOME/.local/share inside the sandbox vanishes (the sandbox home is not persisted to the host). Stage to $XDG_DATA_HOME instead, which Flatpak persists to ~/.var/app/<id>/data (host-visible, no extra permission needed). Reverts the unnecessary --filesystem=home (and the profiles behavior change it would introduce). README now points at ~/.var/app/.../data. - The helper service crash on minimal Arch is an exec/load failure: the tarball bundles no runtime libraries, so the Qt6/KF6/Polkit/PipeWire- linked helper can't start where those are missing. install.sh now ldd- checks the helper and aborts with the missing sonames + per-distro install commands instead of an opaque service failure. Refs #28 * fix(install): bundle helper runtime libs so it runs without system Qt6 The release tarball's couchplay-helper is dynamically linked against system Qt6/Polkit/PipeWire but bundles none, so on minimal distros (e.g. Arch) it fails to start — the opaque exit / ERRNO 2 from #28. Bundle the helper's non-glibc runtime libs into lib/couchplay with a $ORIGIN-relative RPATH via patchelf: - scripts/bundle-libs.sh: ldd-gather deps (excluding glibc/ld-linux), copy, patchelf --set-rpath $ORIGIN/../lib/couchplay - release.yml: add patchelf, run bundle-libs.sh in the Package step - install-helper.sh: install/uninstall lib/couchplay to $PREFIX/lib/couchplay The helper now starts with zero system Qt6. glibc/ld-linux stay system-provided, so the binary still has the build container's glibc floor. The GUI still needs system Qt6 — a portable GUI is the AppImage's job (#30). Refs #28 * docs(install): restructure README — chooser + Flatpak/tarball/AppImage priority Lead the install section with a 'which method should I use?' table and order the methods by broad suitability: Flatpak (universal) -> tarball (curl one-liner + manual/Bazzite) -> AppImage (portable GUI). Consolidate the curl quick-install and manual tarball steps under one Tarball section, and fold the AppImage docs in here so this PR owns all install documentation. Refs #28 * docs: drop AppImage install method from README CouchPlay's entire function depends on the privileged root helper, which cannot run from an AppImage mount and always needs a system install. That nullifies AppImage's core 'just download and run' promise for this app, and Flatpak already covers the universal/portable case (without AppImage's glibc floor). Keep Flatpak + tarball/curl only. * fix(review): force-rpath transitivity, guard empty lib glob, fix usage() path Address code-review findings on PR #29: - bundle-libs.sh: add --force-rpath so the helper gets DT_RPATH (transitive), not DT_RUNPATH. Without it the bundled transitive libs (Qt6Core's libpcre2/libdouble-conversion/libzstd) are unreachable on minimal systems and the helper still fails to load — defeating the #28 fix. - install-helper.sh: guard the bundled-lib install with compgen -G so an empty lib dir doesn't abort the root install mid-way under set -e (partial install). - install-helper.sh: usage() now prints the resolved $EXPORT_DIR instead of the stale hardcoded ~/.local/share/couchplay (which doesn't exist on host in Flatpak). Finding C (install derefs symlinks) is N/A: bundle-libs.sh uses cp -L upstream, so lib/couchplay holds flattened real files, no symlinks reach the install step. --------- Co-authored-by: hikaps <hikaps@users.noreply.github.com>
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.
Summary
Adds a portable AppImage distribution: the GUI bundled with its Qt6/KF6 runtime libraries, so it runs on current x86_64 desktops without installing Qt6/KF6 system-wide. Came out of the #28 install discussion as a "runs anywhere" option alongside Flatpak.
How it's structured
couchplay): bundled vialinuxdeploy+linuxdeploy-plugin-qt(Qt plugins, QML imports, libs). Runs from the AppImage against the bundled runtime.Type=dbusdaemon). So it's carried inside and installed on demand via a customAppRunsubcommand:install-helper.sh installwithsudo— landing the helper in system paths exactly like the tarball. The helper then uses system Qt6/Polkit (the AppImage's bundled libs are for the GUI only); missing ones are reported by the dep-detection ininstall-helper.sh/install.sh.Files
scripts/AppRun— custom AppRun: launches GUI by default;install-helpersubcommand extracts + installs the privileged helper.scripts/build-appimage.sh— builds, fetches linuxdeploy/Qt-plugin/appimagetool, bundles the GUI, packages the AppImage..github/workflows/appimage.yml—fedora:40container (glibc 2.39 baseline), triggers onv*tags +workflow_dispatch, uploads the AppImage to the release.README.md— AppImage install section.Portability
glibc forward-compat means the AppImage runs on any distro with glibc ≥ the build baseline.
fedora:40(glibc 2.39) covers Arch/CachyOS, Fedora, Ubuntu 24.04 LTS, Debian 13, openSUSE Tumbleweed. It will not run on Debian 12 / Ubuntu 22.04 LTS (older glibc); the workflow file documents how to lower the baseline (requires KF6 available on the older base — not in their default repos, so it's a follow-up). Flatpak remains the zero-glibc-constraint method.I could not build this locally (full KDE/Qt6 toolchain in a Fedora container). Verified so far:
bash -nclean onAppRunandbuild-appimage.sh; YAML valid.LD_LIBRARY_PATH/QT_PLUGIN_PATH/QML2_IMPORT_PATH) and theinstall-helperextraction layout matchinstall-helper.sh's release-tarball structure detection.To validate, trigger the workflow on this branch:
Things to confirm on that run: (a)
fedora:40resolves thekf6-*/qt6-*dnf deps, (b)linuxdeploy+ Qt plugin bundle the Wayland platform plugin correctly, (c) the resulting AppImage boots the GUI on a clean system, (d)install-helperextracts and installs the helper.Out of scope (follow-ups)
install-helper.shlib-dir install) so the helper also runs without system Qt6 — that's the change that would make how to install on cachyos? #28's helper fully portable.Refs #28