Qt für Linux/X11 - Einsatz
In dieser Dokumentation werden spezielle Probleme bei der Bereitstellung von Qt für Linux/X11 behandelt. Wir werden die Verfahren anhand der Bereitstellung der Plug & Paint-Beispielanwendung demonstrieren, die mit dem Qt-Quellpaket geliefert wird.
Aufgrund der Vielzahl von Unix-Systemen (wie kommerzielle Unixe oder Linux-Distributionen) ist der Einsatz unter Unix ein komplexes Thema. Bevor wir beginnen, sollten Sie sich darüber im Klaren sein, dass Programme, die für eine Unix-Variante kompiliert wurden, wahrscheinlich nicht auf einem anderen Unix-System laufen werden. Wenn Sie zum Beispiel keinen Cross-Compiler verwenden, können Sie Ihre Anwendung nicht auf Irix kompilieren und sie auf AIX verteilen.
Gemeinsam genutzte Bibliotheken
Bei der Bereitstellung der Anwendung plugandpaint unter Verwendung des Ansatzes der gemeinsam genutzten Bibliotheken gibt es zwei Herausforderungen: Die Qt-Laufzeitumgebung muss zusammen mit der ausführbaren Anwendung korrekt verteilt werden, und die Plugins müssen an der richtigen Stelle auf dem Zielsystem installiert werden, damit die Anwendung sie finden kann.
Qt als Shared Library bauen
Wir gehen davon aus, dass Sie Qt bereits als Shared Library installiert haben, was bei der Installation von Qt standardmäßig der Fall ist, und zwar im Verzeichnis /path/to/Qt.
Verknüpfen der Anwendung mit Qt als Shared Library
Nachdem wir sichergestellt haben, dass Qt als Shared Library installiert ist, können wir die Anwendung plugandpaint erstellen. Zuerst müssen wir in das Verzeichnis wechseln, das die Anwendung enthält:
cd /path/to/Qt/examples/tools/plugandpaint
Führen Sie nun qmake aus, um ein neues Makefile für die Anwendung zu erstellen, und führen Sie einen sauberen Build durch, um die dynamisch gelinkte ausführbare Datei zu erstellen:
make clean
qmake -config release
makeDies baut die Kernanwendung, die folgenden Schritte werden die Plugins bauen:
cd ../plugandpaint/plugins make clean qmake -config release make
Wenn alles ohne Fehler kompiliert und gelinkt wurde, erhalten wir eine ausführbare Datei plugandpaint und die Plugin-Dateien libpnp_basictools.so und libpnp_extrafilters.so.
Erstellen des Anwendungspakets
Unter Unix gibt es keine Standard-Paketverwaltung, daher ist die unten vorgestellte Methode eine generische Lösung. Lesen Sie in der Dokumentation Ihres Zielsystems nach, wie Sie ein Paket erstellen können.
Um die Anwendung bereitzustellen, müssen wir sicherstellen, dass wir die relevanten Qt-Bibliotheken (entsprechend den in der Anwendung verwendeten Qt-Modulen), das Plattform-Plugin und die ausführbare Datei in denselben Verzeichnisbaum kopieren. Denken Sie daran, dass, wenn Ihre Anwendung von compilerspezifischen Bibliotheken abhängt, diese ebenfalls zusammen mit Ihrer Anwendung weiterverteilt werden müssen. Weitere Informationen finden Sie im Abschnitt Abhängigkeiten von Anwendungen.
Wir werden die Plugins in Kürze behandeln, aber das Hauptproblem bei gemeinsam genutzten Bibliotheken ist, dass Sie sicherstellen müssen, dass der dynamische Linker die Qt-Bibliotheken findet. Wenn nicht anders angegeben, durchsucht der dynamische Linker nicht das Verzeichnis, in dem sich Ihre Anwendung befindet. Es gibt viele Möglichkeiten, dieses Problem zu lösen:
- Sie können die Qt-Bibliotheken in einem der Systembibliothekenpfade installieren (z.B.
/usr/libauf den meisten Systemen). - Sie können beim Linken der Anwendung einen vorgegebenen Pfad an die Kommandozeilenoption
-rpathübergeben. Dadurch wird der dynamische Linker angewiesen, beim Starten Ihrer Anwendung in diesem Verzeichnis zu suchen. - Sie können ein Startskript für Ihre Anwendung schreiben, in dem Sie die Konfiguration des dynamischen Linkers ändern (z. B. indem Sie das Verzeichnis Ihrer Anwendung zur Umgebungsvariablen
LD_LIBRARY_PATHhinzufügen).Hinweis: Wenn Ihre Anwendung mit der Option "Setze Benutzer-ID bei Ausführung" ausgeführt wird und wenn sie root gehört, wird LD_LIBRARY_PATH auf einigen Plattformen ignoriert. In diesem Fall ist die Verwendung des LD_LIBRARY_PATH-Ansatzes keine Option).
Der Nachteil des ersten Ansatzes ist, dass der Benutzer über Superuser-Rechte verfügen muss. Der Nachteil des zweiten Ansatzes besteht darin, dass der Benutzer möglicherweise keine Berechtigung hat, in den vorgegebenen Pfad zu installieren. In beiden Fällen haben die Benutzer nicht die Möglichkeit, in ihr Heimatverzeichnis zu installieren. Wir empfehlen den dritten Ansatz, da er am flexibelsten ist. Ein Skript plugandpaint.sh sieht zum Beispiel so aus:
#!/bin/sh appname=`basename $0 | sed s,\.sh$,,` dirname=`dirname $0` tmp="${dirname#?}" if [ "${dirname%$tmp}" != "/" ]; then dirname=$PWD/$dirname fi LD_LIBRARY_PATH=$dirname export LD_LIBRARY_PATH $dirname/$appname "$@"
Wenn Sie dieses Skript anstelle der ausführbaren Datei ausführen, sind Sie sicher, dass die Qt-Bibliotheken vom dynamischen Linker gefunden werden. Beachten Sie, dass Sie das Skript nur umbenennen müssen, um es mit anderen Anwendungen zu verwenden.
Bei der Suche nach Plugins sucht die Anwendung in einem Plugins-Unterverzeichnis innerhalb des Verzeichnisses der ausführbaren Anwendung. Entweder müssen Sie die Plugins manuell in das Verzeichnis plugins kopieren, oder Sie können die DESTDIR in den Projektdateien der Plugins einstellen:
DESTDIR = /path/to/Qt/plugandpaint/plugins
Ein Archiv, das alle Qt-Bibliotheken und alle Plugins enthält, die für die Ausführung der Anwendung plugandpaint erforderlich sind, müsste die folgenden Dateien enthalten:
| Komponente | Datei Name | |
|---|---|---|
| Die ausführbare Datei | plugandpaint | |
| Das Skript zum Ausführen der ausführbaren Datei | plugandpaint.sh | |
| Das Basic Tools-Plugin | plugins\libpnp_basictools.so | |
| Das ExtraFilters-Plugin | plugins\libpnp_extrafilters.so | |
| Das Qt xcb Plattform-Plugin | platforms\libqxcb.so | |
| Das Modul Qt Core | libQt6Core.so.6 | |
| Das Qt GUI Modul | libQt6Gui.so.6 | |
| Das Qt Widgets Modul | libQt6Widgets.so.6 | |
Auf den meisten Systemen ist die Erweiterung für gemeinsame Bibliotheken .so. Eine bemerkenswerte Ausnahme ist HP-UX, das .sl verwendet.
Denken Sie daran, dass, wenn Ihre Anwendung von compilerspezifischen Bibliotheken abhängt, diese trotzdem zusammen mit Ihrer Anwendung weitergegeben werden müssen. Weitere Informationen finden Sie im Abschnitt Anwendungsabhängigkeiten.
Um zu überprüfen, ob die Anwendung nun erfolgreich bereitgestellt werden kann, können Sie dieses Archiv auf einem Rechner ohne Qt und ohne installierten Compiler entpacken und versuchen, es auszuführen, d. h. das Skript plugandpaint.sh ausführen.
Eine Alternative zum Ablegen der Plugins im Unterverzeichnis plugins ist das Hinzufügen eines benutzerdefinierten Suchpfades, wenn Sie Ihre Anwendung mit QApplication::addLibraryPath() oder QApplication::setLibraryPaths() starten.
QCoreApplication::addLibraryPath("/some/other/path");
Statische Verlinkung
Statisches Linken ist oft der sicherste und einfachste Weg, eine Anwendung unter Unix zu verteilen, da es Sie von der Aufgabe entbindet, die Qt-Bibliotheken zu verteilen und sicherzustellen, dass sie sich im Standardsuchpfad für Bibliotheken auf dem Zielsystem befinden.
Qt statisch bauen
Um diesen Ansatz zu verwenden, müssen Sie damit beginnen, eine _statische_ Version der Qt-Bibliotheken zu erstellen. Folgen Sie den Schritten in Qt für Linux/X11 - Erstellen vom Quellcode, aber denken Sie daran, ein -static Argument zur Konfiguration hinzuzufügen:
mkdir -p ~/dev/qt-build cd ~/dev/qt-build /tmp/qt-everywhere-src-6.10.1/configure -static
Linken der Anwendung mit der statischen Version von Qt
Sobald Qt statisch gebaut ist, besteht der nächste Schritt darin, das Makefile zu regenerieren und die Anwendung neu zu erstellen. Zuerst müssen wir in das Verzeichnis wechseln, das die Anwendung enthält:
cd /path/to/Qt/examples/widgets/tools/plugandpaint/app
Führen Sie nun qmake aus, um ein neues Makefile für die Anwendung zu erstellen, und führen Sie einen sauberen Build durch, um die statisch gelinkte ausführbare Datei zu erzeugen:
make clean PATH=/path/to/Qt/bin:$PATH export PATH qmake -config release make
Wahrscheinlich wollen Sie gegen die Release-Bibliotheken linken, und Sie können dies beim Aufruf von qmake angeben. Beachten Sie, dass wir den Pfad zu dem statischen Qt, das wir gerade gebaut haben, angeben müssen.
Um zu überprüfen, ob die Anwendung wirklich statisch mit Qt gelinkt ist, führen Sie das Tool ldd aus (auf den meisten Unix-Systemen verfügbar):
ldd ./application
Stellen Sie sicher, dass die Qt-Bibliotheken in der Ausgabe nicht erwähnt werden.
Vorausgesetzt, dass alles fehlerfrei kompiliert und gelinkt wurde, sollten wir nun eine plugandpaint Datei haben, die bereit für den Einsatz ist. Eine einfache Möglichkeit zu überprüfen, ob die Anwendung wirklich eigenständig ausgeführt werden kann, besteht darin, sie auf einen Rechner zu kopieren, auf dem weder Qt noch andere Qt-Anwendungen installiert sind, und sie auf diesem Rechner auszuführen.
Denken Sie daran, dass, wenn Ihre Anwendung von compilerspezifischen Bibliotheken abhängt, diese trotzdem zusammen mit Ihrer Anwendung weiterverteilt werden müssen. Weitere Informationen finden Sie im Abschnitt Anwendungsabhängigkeiten.
Das Plug & Paint Beispiel besteht aus mehreren Komponenten: Die Kernanwendung(Plug & Paint) und die Plugins Basic Tools und Extra Filters. Da wir Plugins nicht mit dem statischen Linking-Ansatz bereitstellen können, ist die von uns bisher vorbereitete ausführbare Datei unvollständig. Die Anwendung wird zwar ausgeführt, aber die Funktionalität ist aufgrund der fehlenden Plugins deaktiviert. Um Plugin-basierte Anwendungen einzusetzen, sollten wir den Shared-Library-Ansatz verwenden.
Abhängigkeiten der Anwendung
Zusätzliche Bibliotheken
Um herauszufinden, von welchen Bibliotheken Ihre Anwendung abhängt, führen Sie das Tool ldd aus (auf den meisten Unix-Systemen verfügbar):
ldd ./application
Es listet alle Shared-Library-Abhängigkeiten für Ihre Anwendung auf. Je nach Konfiguration müssen diese Bibliotheken zusammen mit Ihrer Anwendung weiterverteilt werden. Insbesondere die C++-Standardbibliothek muss neu verteilt werden, wenn Sie Ihre Anwendung mit einem Compiler kompilieren, der binär nicht mit dem Systemcompiler kompatibel ist. Wenn möglich, ist es die sicherste Lösung, statisch gegen diese Bibliotheken zu linken.
Sie werden wahrscheinlich dynamisch mit den regulären X11-Bibliotheken linken wollen, da einige Implementierungen versuchen werden, andere gemeinsam genutzte Bibliotheken mit dlopen() zu öffnen, und wenn dies fehlschlägt, könnte die X11-Bibliothek Ihre Anwendung zum Absturz bringen.
Es ist auch erwähnenswert, dass Qt nach bestimmten X11-Erweiterungen, wie Xinerama und Xrandr, sucht und sie möglicherweise einbindet, einschließlich aller Bibliotheken, gegen die sie linken. Wenn Sie das Vorhandensein einer bestimmten Erweiterung nicht garantieren können, ist es am sichersten, sie bei der Konfiguration von Qt zu deaktivieren (zum Beispiel ./configure -no-xrandr).
FontConfig und FreeType sind weitere Beispiele für Bibliotheken, die nicht immer zur Verfügung stehen oder nicht immer binärkompatibel sind. So seltsam es auch klingen mag, einige Softwarehersteller hatten Erfolg, indem sie ihre Software auf sehr alten Rechnern kompilierten und sehr darauf achteten, die darauf laufende Software nicht zu aktualisieren.
Wenn Sie Ihre Anwendung gegen die statischen Qt-Bibliotheken linken, müssen Sie explizit mit den oben erwähnten abhängigen Bibliotheken linken. Dazu fügen Sie sie der Variable LIBS in Ihrer Projektdatei hinzu.
Qt-Plugins
Alle Qt GUI Anwendungen benötigen ein Plugin, das die Qt Platform Abstraction (QPA) Schicht in Qt implementiert. Für Linux/X11 lautet der Name des Plattform-Plugins libqxcb.so. Diese Datei muss sich in einem bestimmten Unterverzeichnis (standardmäßig platforms) unter Ihrem Distributionsverzeichnis befinden. Alternativ ist es möglich, den Suchpfad anzupassen, den Qt verwendet, um seine Plugins zu finden, wie unten beschrieben.
Ihre Anwendung kann auch von einem oder mehreren Qt-Plugins abhängen, wie z.B. dem JPEG-Bildformat-Plugin oder einem SQL-Treiber-Plugin. Vergewissern Sie sich, dass Sie alle Qt-Plugins, die Sie benötigen, mit Ihrer Anwendung verteilen. Ähnlich wie beim Plattform-Plugin muss sich jedes Plugin in einem bestimmten Unterverzeichnis (z.B. imageformats oder sqldrivers) in Ihrem Distributionsverzeichnis befinden.
Der Suchpfad für Qt-Plugins (sowie einige andere Pfade) ist in der Bibliothek QtCore fest einprogrammiert. Standardmäßig ist der erste Plugin-Suchpfad als /path/to/Qt/plugins fest programmiert. Wie bereits erwähnt, hat die Verwendung vorgegebener Pfade gewisse Nachteile, so dass Sie verschiedene Alternativen prüfen müssen, um sicherzustellen, dass die Qt-Plugins gefunden werden:
- Die Verwendung von
qt.conf. Dies ist der empfohlene Ansatz, da er die größte Flexibilität bietet. - Verwendung von QApplication::addLibraryPath() oder QApplication::setLibraryPaths().
- Verwendung eines Installationsprogramms eines Drittanbieters oder des Paketmanagers des Zielsystems, um die fest kodierten Pfade in der Bibliothek QtCore zu ändern.
Das Dokument How to Create Qt Plugins (Wie man Qt-Plugins erstellt ) umreißt die Punkte, auf die Sie bei der Erstellung und Bereitstellung von Plugins für Qt-Anwendungen achten müssen.
Exemplarische Vorgehensweise: Ein DEB-Paket erstellen
Dieser Abschnitt beschreibt, wie Sie ein DEB-Paket für Ihre Qt-Anwendung unter Linux mithilfe der CMake Deployment-API erstellen, die in Qt 6.5 oder neuer verfügbar ist. Es gibt kein spezielles linuxdeployqt Tool. Die aktuelle Lösung verlässt sich ausschließlich auf die in CMake integrierte Funktionalität.
Beispielhafte Projekteinrichtung
Beginnen Sie mit einem einfachen CMake-Projekt:
cmake_minimum_required(VERSION 3.22) project(MyApp) find_package(Qt6 REQUIRED COMPONENTS Widgets) qt_standard_project_setup() qt_add_executable(MyApp main.cpp) target_link_libraries(MyApp PRIVATE Qt::Widgets)
Schritt 1: Bereiten Sie die Installation vor
Fügen Sie Befehle zur Installation der Anwendung und zur Erstellung eines Deployment-Skripts hinzu, um ein in sich geschlossenes Verzeichnis zu erstellen:
# Install the executable to "${CMAKE_INSTALL_PREFIX}/bin".
install(TARGETS MyApp
BUNDLE DESTINATION .
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
# Generate the deployment script for MyApp.
qt_generate_deploy_app_script(
TARGET MyApp
FILENAME_VARIABLE deploy_script
NO_UNSUPPORTED_PLATFORM_ERROR
)
# Run the deployment script during installation (on "cmake --install").
install(SCRIPT ${deploy_script})Bauen und installieren Sie das Projekt:
qt-cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/tmp/my-application .. cmake --build . cmake --install .
Das Deployment-Skript:
- Erzeugt eine qt.conf-Datei neben der ausführbaren Datei, die Informationen über das Verzeichnislayout enthält. Diese wird zur Laufzeit benötigt, um die Plugins und Assets zu finden. Siehe die qt.conf-Dokumentation für Details.
- Untersucht die ausführbare Datei und die verwendeten Qt-Plugins mit der in CMake integrierten Datei (GET_RUNTIME_DEPENDENCIES), um festzustellen, welche Qt-Bibliotheken eingesetzt werden sollen.
- Installiert die notwendigen Qt-Plugins und Qt-Bibliotheken.
Das Installationsverzeichnis kann nun auf einen anderen Rechner kopiert werden, und die Anwendung sollte weiterhin funktionieren.
Schritt 2: Erstellen des DEB-Pakets
Nach der Installation packen Sie das Verzeichnis mit CPack. Fügen Sie Folgendes zu Ihrem CMake-Projekt hinzu:
set(CPACK_PACKAGE_NAME my-app)
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "My amazing application")
set(CPACK_PACKAGE_VENDOR "My Company")
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
set(CPACK_VERBATIM_VARIABLES ON)
set(CPACK_PACKAGING_INSTALL_PREFIX "/opt/myapp")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Package Maintainer <maintainer@example.com>")
set(CPACK_DEBIAN_PACKAGE_DEPENDS libc6 libstdc++6 libgcc-s1)
include(CPack)Rekonfigurieren Sie das Projekt, navigieren Sie zum Build-Verzeichnis (es muss die Datei CPackConfig.cmake enthalten), und führen Sie CPack aus, um das DEB-Paket zu erzeugen:
cpack -G DEB
Um den Inhalt des Pakets zu prüfen:
dpkg -c my_app-1.0-Linux.deb
Um das Paket zu installieren:
sudo dpkg -i my_app-1.0-Linux.deb
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.