Version-less CMake targets (Qt 5.15)
April 16, 2020 by Kai Köhne | Comments
We are working full steam on porting Qt 6 to CMake as the internal build system. While Qt 6 is still some months away, you can see already some benefits of this work in Qt 5.15. Cristian Adam already blogged about improvements in CMake 3.17, and how for instance AUTOMOC in QT 5.15 got improved. This blog post is about how you can prepare for Qt 6 in your CMake projects ...
Looking back: Qt 4 to Qt 5
While Qt 4 to Qt 5 was largely source compatible in terms of C++, this was unfortunately not the case for the CMake integration itself. You had sometimes to adapt much of your CMake code that dealt with integrating Qt, see KDAB's blog post from 2012 about some of the issues.
Nowadays CMake is much more common for Qt projects, and the CMake support itself has matured a lot. Hence we do not plan to do any drastic changes in the integration, but instead try to make the transition as smooth as possible ...
The issue: Versioned targets and commands
One obvious issue is that basically all of the CMake API (targets, variables, commands) that Qt provides contains the Qt major version in the name. This is true even for the very simple examples:
project(hellotr LANGUAGES CXX)
find_package(Qt5 COMPONENTS Widgets LinguistTools REQUIRED)
Now you can argue that - provided that the actual semantics do not change - replacing all Qt5::, qt5_ calls in your CMake file with Qt6::, qt6_ is simple enough. This is true, but doesn't help you if you want to support both Qt 5 and Qt 6 for a while.
Version-less targets and commands
So let me introduce the new version-less targets and commands in Qt 5.15. Above example can be written as:
project(hellotr LANGUAGES CXX)
find_package(Qt5 5.15 COMPONENTS Widgets LinguistTools REQUIRED)
Except for the find_package call this should work for Qt 6 too.
If you are wondering about the additional 5.15 argument to find_package: This lets CMake error out with an appropriate error message if your Qt version is older than Qt 5.15.
You can opt out of these new targets and commands by setting
QT_NO_CREATE_VERSIONLESS_FUNCTIONS variables before find_package. This is helpful for instance if you have defined these already yourself, or if you (for reasons that are beyond my imagination) want to still access Qt 3's qt_wrap_cpp ...
Mixing Qt 5 and Qt 6
Let me start with a big disclaimer: Qt doesn't support mixing different Qt versions in one application! Anyhow, there are advanced use cases where you might want to build separate artifacts using Qt 5 and Qt 6 in one project.
For these cases, you can define the new
QT_DEFAULT_MAJOR_VERSION variable to either 5 or 6. If this variable is set before the find_package call loading either Qt5 or Qt 6, the versionless functions will use the logic from the respective Qt version.
With Qt 5.15 nearing it's first release, we will be more and more conservative in touching the existing CMake infrastructure in this version. Anyhow, we plan to still improve the documentation on how to best use CMake with Qt.
For Qt 6, we will see much more API to not only use Qt modules, but also on how to define your own Qt modules and plugins. But this is a topic for a future blog post ...
Subscribe to our newsletter
Try Qt 6.5 Now!
Download the latest release here: www.qt.io/download.
Qt 6.5 is the latest Long-Term-Support release with all you need for C++ cross-platform app development.
Explore Qt World
Check our Qt demos and case studies in the virtual Qt World
Check out all our open positions here and follow us on Instagram to see what it's like to be #QtPeople.
Näytä tämä julkaisu Instagramissa.
Want to build something for tomorrow, join #QtPeople today! We have loads of cool jobs you don't want to miss! http://qt.io/careers #builtwithQt #software #developers #coding #framework #tool #tooling #C++ #QML #engineers #sales #tech #technology #UI #UX #CX #Qt #Qtdev #global #openpositions #careers #job
Henkilön Qt (@theqtcompany) jakama julkaisu