浏览文档

Choosing a format

Most upstreams publish the same release several ways. Pick one download, and the runtime follows from what that download brings with it.

Prefer the tarball (or zip). It is the build upstream made to run from its own directory on any distribution, so it unpacks into one tree that works where it lands. A .deb is the next choice: usually the same files, laid out for a distribution. An AppImage carries the most with it and needs an extra tool to open, so it comes last, with one exception: Qt apps, where the AppImage is often the better choice.

Format Unpack Runtime it usually needs Page
tar / zip bsdtar Whatever the app links: freedesktop for Electron and self-contained builds, GNOME for GTK and WebKitGTK Tarballs and zips
.deb bsdtar twice Same; GNOME for Tauri Debian packages
AppImage appimage-tools from prebuilt freedesktop: it brings its own toolkit AppImages
.rpm bsdtar Same as .deb Debian packages

The Qt exception

A Qt app’s tarball or .deb is linked against a system Qt, so it needs org.kde.Platform. That is a large runtime most users don’t have, and only one app in the catalog uses it. Worse, a Qt binary built for a distribution often crashes on the KDE runtime’s Qt (see the details below). If upstream also ships an AppImage that carries its own Qt, unpack that instead and run it on org.freedesktop.Platform: nothing Qt comes from the runtime, and the app needs only the small base every Flatpak user already has.

The reference package is Mark Shot (Qt 6); its manifest explains each choice.

For agents

Choosing the runtime

The payload Runtime Examples
Electron or another bundled Chromium org.freedesktop.Platform 26.08 + base: org.electronjs.Electron2.BaseApp Folo, Electerm
Self-contained (its own toolkit or Qt) org.freedesktop.Platform 26.08 Mark Shot, Compass
GTK 3/4, libadwaita, WebKitGTK (Tauri, Wails) org.gnome.Platform 51 Tabularis, Grab
Linked to a system Qt, no self-contained build org.kde.Platform 6.11, only after testing HeidiSQL

Find what the binary links before choosing: unpack the download and run readelf -d <binary> | grep NEEDED on the main binary and its bundled libraries. Every NEEDED library has to come from the runtime, the payload, or flatpark/prebuilt. Choose the smallest runtime that covers them; GNOME and KDE are both much larger than freedesktop, and an app is only worth one if it uses what they add.

Why a distribution’s Qt binary fails on the KDE runtime

A Qt executable built by a distribution carries R_X86_64_COPY relocations for QCoreApplication::self and for the staticMetaObject of QObject, QWidget and the app’s own classes. The KDE runtime’s Qt reads and writes its own copies of those instead of going through the GOT, so the two diverge: the process dies in QApplication’s constructor, and once past that, qobject_cast inside the Qt libraries stops matching — windows close as soon as they open. Environment variables don’t reach it. A self-contained payload never consults the runtime’s Qt and is unaffected. Mark Shot’s manifest has the full trace.

HeidiSQL works on the KDE runtime because it is a Lazarus app talking to Qt through libQt6Pas, not a C++ Qt program; it is the exception, not a model.

Things to check in a self-contained AppImage

  • Which Qt platform plugins it ships. Many carry only xcb. Then use --socket=x11 (not fallback-x11, which withholds X11 on a Wayland session), --unset-env=QT_QPA_PLATFORM in finish-args, and QT_QPA_PLATFORM="${QT_QPA_PLATFORM:-xcb}" in the wrapper, so a user override still wins. Qt 5 bundles often ship the Wayland plugin without libQt5WaylandClient, which fails the same way; pin those to xcb too.
  • What it deliberately leaves out. AppImages leave the display, GL, fonts, glib and audio stacks to the host. Those are exactly what the freedesktop runtime provides, which is why it is enough.
  • Whether its launcher sets library paths. Some AppImages rely on AppRun to set LD_LIBRARY_PATH or QT_PLUGIN_PATH. Read it, and reproduce the same variables in the wrapper; don’t run AppRun itself unless it is a plain shell script that only sets variables.

When upstream ships something else

  • Only an installer script or .run file: extract what it would install without running it (many are a shell header on a tarball). If it can only be run, running it unmodified at first launch is not a change; if it only works with parts stood in for (a fake df, a patched check), the package is Modified and closed-source only.
  • Only a Windows installer: packaged on top of Cellar, FlatPark’s Wine runner.
  • Only source: not packageable here; see the limits.

在 GitHub 上编辑此页