Kompatibilität von Qt 5 und Qt 6

Die Semantik der CMake-API in Qt 5 und Qt 6 ist weitgehend kompatibel, obwohl es einige Unterschiede im Verhalten dieser Befehle und zusätzliche Schnittstellen nur in den letzteren Versionen gibt. Dieser Leitfaden ist in erster Linie für Projekte gedacht, die eine schrittweise Migration von einer Hauptversion zur anderen planen.

Bis Qt 5.14 enthielten alle importierten Qt-Bibliotheksziele und Befehle die Versionsnummer als Teil des Namens, zum Beispiel qt5_add_library. 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, z.B. qt_add_library, 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. Um die Qt 6 Prüfung zu überspringen, setzen Sie CMAKE_DISABLE_FIND_PACKAGE_Qt6 vor dem Aufruf von find_package.

Die versionslosen Targets sind standardmäßig definiert. Setzen Sie QT_NO_CREATE_VERSIONLESS_TARGETS vor dem ersten find_package() -Aufruf, um sie zu deaktivieren.

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, seien Sie hier also 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 Qt 5 Versionen älter als 5.15

Wenn Sie auch Qt 5 Versionen unterstützen wollen, die älter als Qt 5.15 sind, können Sie dies tun, indem Sie die aktuelle Version in einer CMake-Variablen (QT_VERSION_MAJOR) speichern:

find_package(Qt6 COMPONENTS Core)
if(Qt6_FOUND)
    set(QT_VERSION_MAJOR 6)
else()
    find_package(Qt5 REQUIRED COMPONENTS Core)
    set(QT_VERSION_MAJOR 5)
endif()

add_executable(helloworld
    ...
)

target_link_libraries(helloworld PRIVATE Qt${QT_VERSION_MAJOR}::Core)

Im Vergleich zum versionslosen Ansatz zeigen die Targets auf Qt${QT_VERSION_MAJOR}::Core, das beim Aufruf von target_link_libraries entweder in Qt5::Core oder Qt6::Core aufgelöst wird.

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 Ziele hat mehrere Nachteile.

Die versionslosen Ziele sind in der Regel ALIAS Ziele, und Sie können kein ALIAS Ziel erstellen, das auf ein ALIAS Ziel zeigt. Verwenden Sie stattdessen die ALIASED_TARGET Ziel-Eigenschaft.

Bei älteren Qt 6-Versionen verfügte das importierte Qt::Core -Ziel nicht über alle Zieleigenschaften, die von Qt6::Core bereitgestellt werden. Dies ist behoben, wenn Sie gegen Qt 6.8 oder neuer, mit CMake 3.18 oder neuer linken.

Projekte dürfen keine Targets exportieren, die versionslose Targets exponieren. Zum Beispiel darf eine Bibliothek, die von einem anderen Projekt konsumiert wird, keine Ziele exportieren, die öffentlich gegen versionslose Ziele linken. 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.