本文翻译自:Version-less CMake targets (Qt 5.15)
原文作者:Kai Köhne
校审:Kenny Zhang, Richard Lin
我们正在全力推进把Qt 6的内部构建系统迁移到CMake。虽然Qt 6离我们还有几个月的时间,但是您已经可以在Qt 5.15中看到这项工作所取得的一些优势。Cristian Adam已经在博客中提到了CMake 3.17中的改进,例如如何改进QT 5.15中的AUTOMOC。这篇博文是关于怎样才能在你的CMake项目中准备好与Qt 6 接轨…
虽然Qt 4到Qt 5在很大程度上在C++源代码级别上是兼容的,但集成CMake却不是这样。你有时不得不调整大部分CMake代码来处理Qt的集成,参见KDAB 2012年的博客文章以了解这些问题的部分内容。
现在CMake在Qt项目中更常见了,CMake支持也成熟了很多。因此,我们不打算在集成上做任何大的改变,而是尽量使迁移平稳地进行……
一个明显的问题是,Qt提供的所有CMake API(目标、变量、命令)基本上都在名称中包含了Qt的主版本号。即使是非常简单的例子也是这样:
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)
现在,您可能想假设实际的语义没有变化----用Qt6::, qt6_替换CMake文件中所有的Qt5::, qt5_调用是非常简单的。这是真的,但是如果要同时支持Qt 5和Qt 6一段时间,这就不行了。
现在让我来介绍Qt 5.15中新的不带版本号的目标和命令。上面的例子可以写成:
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)
如果不是因为find_package调用,这应该也适用于Qt 6。
您可能想知道加在find_package中额外的5.15是什么意思:这是为了能够在您的Qt版本比Qt 5.15老时,产生一个包含合适的错误信息的输出。
您可以在find_package之前设置QT_NO_CREATE_VERSIONLESS_TARGETS或QT_NO_CREATE_VERSIONLESS_FUNCTIONS变量来选择不使用这些新目标和命令。这是有意义的,例如,如果你已经自己定义了这些,或者如果你(我很难想象)仍然想要访问Qt 3的qt_wrap_cpp…
让我以一个重要的免责声明开始:Qt不支持在一个应用程序中混合不同的Qt版本!不管怎样,在一些高级用例中,您可能希望在一个项目中使用Qt 5和Qt 6构建单独的程序。
对于这些情况,您可以将新的QT_DEFAULT_MAJOR_VERSION变量定义为5或6。如果这个变量是在加载Qt5或Qt 6的find_package调用之前设置的,那么不带版本号的函数将使用相应Qt版本的逻辑。
随着Qt 5.15第一个版本即将发布,我们将越来越谨慎地修改这个版本中现有的CMake基础架构。无论如何,我们仍然计划改进文档,以更好地使用Qt中的CMake。
对于Qt 6,我们将会看到更多的API,不仅可以使用Qt模块,还可以定义自己的Qt模块和插件。这是以后博文的主题……