Distributing Qt Applications on Linux with linuxdeployqt
Installing linuxdeployqt
Download the prebuilt AppImage for your architecture and place it on your PATH. Then make it executable and verify the version.
chmod +x linuxdeployqt-x86_64.AppImage
sudo mv linuxdeployqt-x86_64.AppImage /usr/local/bin/linuxdeployqt
linuxdeployqt --version
# Example output
# linuxdeployqt 5 (commit 37631e5), build 631 built on 2019-01-25 22:47:58 UTC
Qt environment variables
Append environment configuration to your shell profile. Replace /opt/Qt/5.15.2/gcc_64 with your Qt installation root.
# Qt toolchain
export QT_HOME=/opt/Qt/5.15.2/gcc_64
export PATH="$QT_HOME/bin:$PATH"
export LD_LIBRARY_PATH="$QT_HOME/lib:${LD_LIBRARY_PATH:-}"
export QT_PLUGIN_PATH="$QT_HOME/plugins:${QT_PLUGIN_PATH:-}"
export QML2_IMPORT_PATH="$QT_HOME/qml:${QML2_IMPORT_PATH:-}"
Apply the changes immediately:
source ~/.bashrc
Bundling a Qt application
- Build a Release configuration (shadow build recommended) to produce the executable, e.g., cleanrobot from build-cleanrobot-Desktop_Qt_5_15_2_GCC_64bit-Release.
- Create a publish directory and copy the executable into it.
- Run linuxdeployqt with AppImage generation enabled.
mkdir -p ~/publish/cleanrobot
cp /path/to/build-cleanrobot-Desktop_Qt_5_15_2_GCC_64bit-Release/cleanrobot ~/publish/cleanrobot/
cd ~/publish/cleanrobot
linuxdeployqt ./cleanrobot -appimage
If no desktop file is present, linuxdeployqt will create a stub that you can edit:
ERROR: Desktop file missing, creating a default one (you will probably want to edit it)
Dependenceis (Qt libraries, plugins, QML imports) are copied into the application directory.
Desktop entry (optional)
Place the .desktop file system-wide or for the current user.
# System-wide
# /usr/share/applications/cleanrobot.desktop
# Per-user
# ~/.local/share/applications/cleanrobot.desktop
Example desktop file:
[Desktop Entry]
Version=1.0
Name=CleanRobot
Comment=Utility built with Qt
Exec=/opt/cleanrobot/launch.sh
Icon=/opt/cleanrobot/icons/cleanrobot.png
Terminal=false
Type=Application
Categories=Utility;
Launcher script
Create a wrapper that sets runtime paths relative to the application directory.
vim launch.sh
Script content:
#!/usr/bin/env bash
set -euo pipefail
BASE_DIR="$(cd "$(dirname "$0")" && pwd)"
export LD_LIBRARY_PATH="$BASE_DIR/lib:${LD_LIBRARY_PATH:-}"
export QT_PLUGIN_PATH="$BASE_DIR/plugins:${QT_PLUGIN_PATH:-}"
export QML2_IMPORT_PATH="$BASE_DIR/qml:${QML2_IMPORT_PATH:-}"
exec "$BASE_DIR/cleanrobot" "$@"
Make it executable:
chmod +x launch.sh
Building a Debian package
Create a package root, install path (e.g., /opt/cleanrobot), and control metadata, then build the .deb.
cd ~
mkdir -p pkgroot/opt/cleanrobot
cp -a ~/publish/cleanrobot/* pkgroot/opt/cleanrobot/
mkdir -p pkgroot/DEBIAN
DEBIAN/control:
Package: cleanrobot
Version: 1.0.1
Section: utils
Priority: optional
Architecture: amd64
Depends:
Installed-Size: 512
Maintainer: Example Maintainer
Description: CleanRobot Qt application
Build and install:
dpkg-deb --build pkgroot ~/cleanrobot_1.0.1_amd64.deb
sudo dpkg -i ~/cleanrobot_1.0.1_amd64.deb
The files will be placed under /opt/cleanrobot, and you can run the launcher script from there.
Notes on qt.conf
qt.conf controls runtime search paths used by Qt to locate libraries, plugins, and QML imports relative to the executable.
# Generated by linuxdeployqt
[Paths]
Prefix=.
Libraries=lib
Plugins=plugins
Imports=qml
Qml2Imports=qml