Die Qt-Entwickler arbeiten daran, Qt 6 auf CMake als internes Build-System zu portieren. Während Qt 6 noch einige Monate entfernt ist, können Sie einige der Vorteile dieser Arbeit bereits in Qt 5.15 sehen. Christian Adam hat bereits über die Verbesserungen in CMake 3.17 gebloggt und wie sich zum Beispiel AUTOMOC in QT 5.15 verbessert hat. In diesem Artikel geht es darum, wie Sie sich in Ihren CMake-Projekten auf Qt 6 vorbereiten können.
Rückblick: von Qt 4 bis Qt 5
Während Qt 4 – Qt 5 aus C++-Perspektive weitgehend quellkompatibel waren, ist dies bei der CMake-Integration selbst leider nicht der Fall. Manchmal musste man einen großen Teil des CMake-Codes anpassen, im Fall der Qt-Integration.
CMake wird jetzt viel häufiger in Qt-Projekten verwendet, und die CMake-Unterstützung selbst ist erheblich ausgereift. Daher planen die Entwickler keine drastischen Änderungen an der Integration, sondern versuchen, den Übergang so reibungslos wie möglich zu gestalten.
Problem: versionierte Ziele und Befehle
Ein offensichtliches Problem besteht darin, dass im Grunde alle von Qt bereitgestellten CMake-APIs (Ziele, Variablen, Befehle) die Hauptversion von Qt in ihrem Namen tragen. Dies gilt sogar für sehr einfache Beispiele:
cmake_minimum_required(VERSION 3.5) project(hellotr LANGUAGES CXX) find_package(Qt5 COMPONENTS Widgets LinguistTools REQUIRED) qt5_add_translation(QM_FILES hellotr_en.ts) add_executable(hellotr main.cpp ${QM_FILES} ) target_link_libraries(hellotr Qt5::Widgets)
Jetzt können Sie argumentieren, dass es einfach genug ist, alle Aufrufe von Qt5::, qt5_ in Ihrer CMake-Datei durch Qt6::, qt6_ zu ersetzen, vorausgesetzt, die tatsächliche Semantik ändert sich nicht. Dies wird Ihnen jedoch nicht helfen, wenn Sie Qt 5 und Qt 6 für eine Weile unterstützen möchten.
Versionslose Ziele und Befehle
Lassen Sie mich also die neuen versionlosen Ziele und Befehle in Qt 5.15 vorstellen. Das obige Beispiel kann wie folgt geschrieben werden:
cmake_minimum_required(VERSION 3.5) project(hellotr LANGUAGES CXX) find_package(Qt5 5.15 COMPONENTS Widgets LinguistTools REQUIRED) qt_add_translation(QM_FILES hellotr_en.ts) add_executable(hellotr main.cpp ${QM_FILES} ) target_link_libraries(hellotr Qt::Widgets)
Mit Ausnahme des find_package-Aufrufs sollte dies auch für Qt 6 funktionieren.
Wenn Sie an dem zusätzlichen 5.15-Argument für find_package interessiert sind: Dadurch kann CMake einen Fehler mit der entsprechenden Fehlermeldung ausgeben, wenn Ihre Version von Qt älter als Qt 5.15 ist.
Sie können diese neuen Ziele und Befehle ablehnen, indem Sie die Variablen QT_NO_CREATE_VERSIONLESS_TARGETS oder QT_NO_CREATE_VERSIONLESS_FUNCTIONS vor find_package setzen. Das ist zum Beispiel sinnvoll, wenn Sie diese bereits selbst definiert haben oder in Qt 3 noch auf qt_wrap_cpp zugreifen möchten.
Qt 5 und Qt 6 mischen
Lassen Sie mich mit einem großen Haftungsausschluss beginnen: Qt unterstützt nicht das Mischen verschiedener Versionen von Qt in derselben Anwendung! Wie auch immer, es gibt fortgeschrittene Anwendungsfälle, in denen Sie separate Artefakte mit Qt 5 und Qt 6 im selben Projekt erstellen können.
Für diese Fälle können Sie die neue Variable QT_DEFAULT_MAJOR_VERSION auf 5 oder 6 setzen. Wenn diese Variable vor einem find_package-Aufruf gesetzt wird, der Qt 5 oder Qt 6 lädt, verwenden die versionslosen Funktionen die Logik der entsprechenden Qt-Version.
Perspektiven für die Zukunft
Da die erste Veröffentlichung von Qt 5.15 näher rückt, werden Entwickler in dieser Veröffentlichung immer konservativer mit dem bestehenden CMake-Framework umgehen. Auf jeden Fall ist geplant, die Dokumentation darüber, wie es produktiver ist, CMake mit Qt zu verwenden, weiter zu verbessern.
In Qt 6 werden wir viele weitere APIs sehen, um nicht nur Qt-Module zu verwenden, sondern auch, wie Sie Ihre eigenen Qt-Module und Plugins definieren können.