本页内容

Qt 5 与 Qt 6 的兼容性

Qt 5 和 Qt 6 中的 CMake API 语义在很大程度上是兼容的,尽管这些命令的行为存在一些差异,且仅在较新版本中增加了额外接口。本指南主要面向计划从一个主要版本逐步迁移到另一个主要版本的项目。

在 Qt 5.14 及更早版本中,所有导入的 Qt 库目标和命令的名称中都包含版本号,例如qt5_add_library 。这使得编写既适用于 Qt 5 又适用于 Qt 6 的 CMake 代码变得有些繁琐。 因此,Qt 5.15 引入了无版本的目标和命令,即qt_add_library ,以便编写在很大程度上与不同 Qt 版本无关的 CMake 代码。

无版本目标

除了现有的导入目标外,Qt 5.15 还引入了无版本目标。也就是说,要链接到 Qt Core ,既可以引用 `Qt6::Core`,也可以引用 `Qt::Core`:

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)

上述代码片段首先尝试查找 Qt 6 安装。如果失败,则尝试查找 Qt 5.15 软件包。无论使用 Qt 6 还是 Qt 5,我们都可以使用导入的Qt::Core 目标。若要跳过 Qt 6 检查,请在 CMAKE_DISABLE_FIND_PACKAGE_Qt6 在调用find_package 之前。

无版本目标默认已定义。若要禁用它们,请在第一个find_package() 调用之前设置QT_NO_CREATE_VERSIONLESS_TARGETS。

无版本命令

自 Qt 5.15 起,Qt 模块还提供了其命令的无版本变体。例如,现在您可以使用qt_add_translation()来编译翻译文件,无论您使用的是 Qt 5 还是 Qt 6。

在首次调用find_package() 之前设置QT_NO_CREATE_VERSIONLESS_FUNCTIONS,以防止创建无版本命令。

混合使用 Qt 5 和 Qt 6

某些项目可能需要在同一个 CMake 上下文中同时加载 Qt 5 和 Qt 6(不过,在同一个库或可执行文件中混合使用不同版本的 Qt 是不受支持的,因此请务必谨慎)。

在此设置下,无版本的目标和命令将隐式引用通过find_package 找到的第一个 Qt 版本。请在首次调用find_package 之前设置QT_DEFAULT_MAJOR_VERSIONCMake 变量,以显式指定该版本。

支持 Qt 5.15 之前的 Qt 5 版本

如果您还需要支持 Qt 5.15 之前的 Qt 5 版本,可以通过将当前版本存储在 CMake 变量(QT_VERSION_MAJOR )中来实现:

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)

与不指定版本的方法相比,目标指向Qt${QT_VERSION_MAJOR}::Core ,该变量在调用target_link_libraries 时会被解析为Qt5::Core 或Qt6::Core 。

尽可能使用 CMake 命令的无版本变体。

除非您必须在同一个项目中同时支持 Qt 5 和 Qt 6,否则请使用带版本的目标。

如果必须使用无版本的目标,请注意使用无版本目标时的注意事项。

如果您需要支持 Qt 5.15 之前的 Qt 5 版本, 或者无法控制 CMake 代码是否在可能定义了QT_NO_CREATE_VERSIONLESS_FUNCTIONS或QT_NO_CREATE_VERSIONLESS_TARGETS的上下文中加载。 在这种情况下,您仍可通过变量确定实际的命令或目标名称来简化代码。

使用无版本目标时的注意事项

使用无版本目标存在若干缺点。

无版本目标通常是ALIAS 目标,且无法创建指向ALIAS 目标的ALIAS 目标。请改用 ALIASED_TARGET 目标属性。

对于较旧的 Qt 6 版本,导入的Qt::Core 目标并未提供Qt6::Core 所公开的所有目标属性。若使用 CMake 3.18 或更高版本并链接至 Qt 6.8 或更高版本,则此问题已得到修复。

项目不得导出暴露无版本目标的目标。例如,被其他项目使用的库不得导出公开链接到无版本目标的目标。否则,传递依赖关系可能会中断,或者该库的用户会无意中混用 Qt5 和 Qt6 目标。

Windows 中的 Unicode 支持

在 Qt 6 中,对于链接到 Qt 模块的目标,默认会设置UNICODE 和_UNICODE 编译器定义。这与 qmake 的行为一致,但与 Qt 5 中 CMake API 的行为相比有所变化。

若要避免设置这些定义,请在目标上调用qt_disable_unicode_defines()。

find_package(Qt6 COMPONENTS Core)

add_executable(helloworld
    ...
)

qt_disable_unicode_defines(helloworld)

© 2026 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.