Kompatibilität von Qt 5 und Qt 6
Die Semantik der CMake-API in Qt 5 und Qt 6 ist weitgehend kompatibel. Bis zu Qt 5.14 enthielten jedoch alle importierten Qt-Bibliotheksziele und Befehle die Versionsnummer als Teil des Namens. Das macht das Schreiben von CMake-Code, der sowohl mit Qt 5 als auch mit Qt 6 funktionieren soll, etwas umständlich. Mit Qt 5.15 wurden daher versionslose Targets und Befehle eingeführt, um das Schreiben von CMake-Code zu ermöglichen, der weitgehend unabhängig von den verschiedenen Qt-Versionen ist.
Versionslose Targets
Zusätzlich zu den bestehenden importierten Targets wurden mit Qt 5.15 versionslose Targets eingeführt. Das heißt, zum Linken gegen Qt Core zu linken, kann man sowohl Qt6::Core
als auch Qt::Core
referenzieren:
find_package(Qt6 COMPONENTS Core) if (NOT Qt6_FOUND) find_package(Qt5 5.15 REQUIRED COMPONENTS Core) endif() add_executable(helloworld ... ) target_link_libraries(helloworld PRIVATE Qt::Core)
Das obige Snippet versucht zunächst, eine Qt 6-Installation zu finden. Wenn das fehlschlägt, versucht es, ein Qt 5.15-Paket zu finden. Unabhängig davon, ob Qt 6 oder Qt 5 verwendet wird, können wir das importierte Qt::Core
Ziel verwenden.
Die versionslosen Targets sind standardmäßig definiert. Setzen Sie QT_NO_CREATE_VERSIONLESS_TARGETS vor dem ersten find_package()
-Aufruf, um sie zu deaktivieren.
Hinweis: Das importierte Qt::Core-Target verfügt nicht über die Target-Eigenschaften, die im Qt6::Core-Target verfügbar sind.
Versionslose Befehle
Seit Qt 5.15 bieten die Qt-Module auch versionslose Varianten ihrer Befehle an. Sie können nun zum Beispiel qt_add_translation verwenden, um Übersetzungsdateien zu kompilieren, unabhängig davon, ob Sie Qt 5 oder Qt 6 verwenden.
Setzen Sie QT_NO_CREATE_VERSIONLESS_FUNCTIONS vor dem ersten find_package()
Aufruf, um die Erstellung von versionslosen Befehlen zu verhindern.
Mischen von Qt 5 und Qt 6
Es könnte Projekte geben, die sowohl Qt 5 als auch Qt 6 in einem CMake-Kontext laden müssen (obwohl das Mischen von Qt-Versionen in einer Bibliothek oder einem Executable nicht unterstützt wird, also sei hier vorsichtig).
In einem solchen Fall beziehen sich die versionslosen Ziele und Befehle implizit auf die erste Qt-Version, die über find_package
gefunden wurde. Setzen Sie die CMake-Variable QT_DEFAULT_MAJOR_VERSION vor dem ersten find_package
-Aufruf, um die Version explizit zu machen.
Unterstützung von älteren Qt 5 Versionen
Wenn Sie auch ältere Qt 5 Versionen als Qt 5.15 unterstützen müssen, können Sie dies tun, indem Sie die aktuelle Version in einer CMake-Variablen speichern:
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core) add_executable(helloworld ... ) target_link_libraries(helloworld PRIVATE Qt${QT_VERSION_MAJOR}::Core)
Hier lassen wir find_package(<PackageName>...)
versuchen, zuerst Qt 6 zu finden, und wenn das fehlschlägt, Qt 5, unter dem Namen QT
. Wenn eines von beiden gefunden wird, ist find_package
erfolgreich, und die CMake-Variable QT_VERSION_MAJOR
wird entweder auf 5
oder 6
definiert.
Wir laden dann das Paket für die ermittelte Qt-Version erneut, indem wir den Namen Qt${QT_VERSION_MAJOR}
on the fly erzeugen. Dies ist notwendig, weil CMAKE_AUTOMOC
erwartet, dass der Paketname entweder Qt5
oder Qt6
ist, und andernfalls einen Fehler ausgibt.
Wir können das gleiche Muster verwenden, um auch den Namen der importierten Bibliothek anzugeben. Bevor target_link_libraries
aufgerufen wird, löst CMake Qt${QT_VERSION_MAJOR}::Widgets
entweder in Qt5::Widgets
oder Qt6::Widgets
auf.
Empfohlene Vorgehensweisen
Verwenden Sie nach Möglichkeit die versionslosen Varianten der CMake-Befehle.
Verwenden Sie die versionierten Targets, es sei denn, Sie müssen Qt 5 und Qt 6 im selben Projekt unterstützen.
Wenn Sie versionslose Targets verwenden müssen, beachten Sie bitte die Fallstricke bei der Verwendung von versionslosen Targets.
Verwenden Sie die versionierten Versionen der CMake Befehle und Targets, wenn Sie Qt 5 Versionen älter als Qt 5.15 unterstützen müssen, oder wenn Sie nicht kontrollieren können, ob Ihr CMake Code in einem Kontext geladen wird, in dem QT_NO_CREATE_VERSIONLESS_FUNCTIONS oder QT_NO_CREATE_VERSIONLESS_TARGETS definiert sein könnten. In diesem Fall können Sie Ihren Code immer noch vereinfachen, indem Sie den tatsächlichen Befehls- oder Zielnamen durch eine Variable bestimmen.
Fallstricke bei der Verwendung von versionslosen Targets
Die Verwendung der versionslosen Targets hat mehrere Nachteile.
Die versionslosen Ziele sind ALIAS
Ziele und verfügen nicht über die Zieleigenschaften der versionierten Ziele.
Projekte dürfen keine Ziele exportieren, die versionslose Ziele offenlegen. So darf beispielsweise eine Bibliothek, die von einem anderen Projekt genutzt wird, keine Ziele exportieren, die öffentlich mit versionslosen Zielen verknüpft sind. Andernfalls könnten transitive Abhängigkeiten unterbrochen werden, oder der Benutzer dieser Bibliothek vermischt ungewollt Qt5- und Qt6-Ziele.
Unicode-Unterstützung in Windows
In Qt 6 sind die Compiler-Definitionen UNICODE
und _UNICODE
standardmäßig für Ziele gesetzt, die gegen Qt-Module gelinkt werden. Dies entspricht dem Verhalten von qmake, ist aber eine Änderung im Vergleich zum Verhalten der CMake API in Qt 5.
Rufen Sie qt_disable_unicode_defines() auf dem Target auf, um die Definitionen nicht zu setzen.
find_package(Qt6 COMPONENTS Core) add_executable(helloworld ... ) qt_disable_unicode_defines(helloworld)
© 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.