cmake-qt(7)

简介

CMake 可以查找和使用 Qt 4、Qt 5 和 Qt 6 库。Qt 4 库通过 CMake 附带的 FindQt4 查找模块找到,而 Qt 5 和 Qt 6 库则使用 Qt 5 和 Qt 6 附带的“配置文件包”找到。有关 CMake 包的更多信息,请参阅 cmake-packages(7),有关您的 Qt 版本的更多信息,请参阅 Qt CMake 手册

Qt 4、Qt 5 和 Qt 6 可以在同一个 CMake 构建系统 中一起使用

cmake_minimum_required(VERSION 3.16 FATAL_ERROR)

project(Qt4_5_6)

set(CMAKE_AUTOMOC ON)

find_package(Qt6 COMPONENTS Widgets DBus REQUIRED)
add_executable(publisher publisher.cpp)
target_link_libraries(publisher Qt6::Widgets Qt6::DBus)

find_package(Qt5 COMPONENTS Gui DBus REQUIRED)
add_executable(subscriber1 subscriber1.cpp)
target_link_libraries(subscriber1 Qt5::Gui Qt5::DBus)

find_package(Qt4 REQUIRED)
add_executable(subscriber2 subscriber2.cpp)
target_link_libraries(subscriber2 Qt4::QtGui Qt4::QtDBus)

CMake 目标不能链接到多个 Qt 版本。如果尝试这样做或由于传递目标依赖评估而导致,则会发出诊断信息。

Qt 构建工具

Qt 依赖一些捆绑工具进行代码生成,例如用于元对象代码生成的 moc、用于小部件布局和填充的 uic 以及用于虚拟文件系统内容生成的 rcc。如果满足适当的条件,cmake(1) 可能会自动调用这些工具。自动工具调用可用于 Qt 4 到 6 版本。

AUTOMOC

AUTOMOC 目标属性控制 cmake(1) 是否检查目标中的 C++ 文件以确定它们是否需要运行 moc,并创建规则以在适当的时候执行 moc

如果在头文件中找到 AUTOMOC_MACRO_NAMES 中的宏,则将对该文件运行 moc。结果将放入一个名为 moc_<basename>.cpp 的文件中。如果在 C++ 实现文件中找到该宏,则 moc 输出将放入一个名为 <basename>.moc 的文件中,遵循 Qt 约定。用户必须在 C++ 实现文件中使用预处理器 #include 包含 <basename>.moc

包含的 moc_*.cpp*.moc 文件将生成在 <AUTOGEN_BUILD_DIR>/include 目录中,该目录会自动添加到目标的 INCLUDE_DIRECTORIES

  • 这与 CMake 3.7 及更早版本不同;有关详细信息,请参阅其文档。

  • 对于 多配置生成器,包含目录是 <AUTOGEN_BUILD_DIR>/include_<CONFIG>

  • 请参阅 AUTOGEN_BUILD_DIR

不包含的 moc_<basename>.cpp 文件将生成在自定义文件夹中,以避免名称冲突,并包含在一个单独的文件中,该文件编译到目标中,命名为 <AUTOGEN_BUILD_DIR>/mocs_compilation.cpp<AUTOGEN_BUILD_DIR>/mocs_compilation_$<CONFIG>.cpp

moc 命令行将使用为其调用的目标的 COMPILE_DEFINITIONSINCLUDE_DIRECTORIES 目标属性,以及适当的构建配置。

通过设置 CMAKE_AUTOMOC 变量,可以预设所有后续目标的 AUTOMOC 目标属性。AUTOMOC_MOC_OPTIONS 目标属性可以填充以设置传递给 moc 的选项。可以填充 CMAKE_AUTOMOC_MOC_OPTIONS 变量以预设所有后续目标的选项。

要搜索的其他宏名称可以添加到 AUTOMOC_MACRO_NAMES

可以使用 AUTOMOC_DEPEND_FILTERS 从源代码中提取额外的 moc 依赖文件名。

通过启用 SKIP_AUTOMOC 或更广泛的 SKIP_AUTOGEN,可以将 C++ 源文件从 AUTOMOC 处理中排除。

AUTOUIC

AUTOUIC 目标属性控制 cmake(1) 是否检查目标中的 C++ 文件以确定它们是否需要运行 uic,并创建规则以在适当的时候执行 uic

如果找到匹配 <path>ui_<basename>.h 的预处理器 #include 指令,并且存在 <basename>.ui 文件,则将执行 uic 以生成相应的文件。<basename>.ui 文件在以下位置搜索:

  1. <source_dir>/<basename>.ui

  2. <source_dir>/<path><basename>.ui

  3. <AUTOUIC_SEARCH_PATHS>/<basename>.ui

  4. <AUTOUIC_SEARCH_PATHS>/<path><basename>.ui

其中 <source_dir> 是 C++ 文件的目录,AUTOUIC_SEARCH_PATHS 是附加搜索路径的列表。

生成的 ui_*.h 文件放置在 <AUTOGEN_BUILD_DIR>/include 目录中,该目录会自动添加到目标的 INCLUDE_DIRECTORIES

  • 这与 CMake 3.7 及更早版本不同;有关详细信息,请参阅其文档。

  • 对于 多配置生成器,包含目录是 <AUTOGEN_BUILD_DIR>/include_<CONFIG>

  • 请参阅 AUTOGEN_BUILD_DIR

通过设置 CMAKE_AUTOUIC 变量,可以预设所有后续目标的 AUTOUIC 目标属性。AUTOUIC_OPTIONS 目标属性可以填充以设置传递给 uic 的选项。可以填充 CMAKE_AUTOUIC_OPTIONS 变量以预设所有后续目标的选项。AUTOUIC_OPTIONS 源文件属性可以在 <basename>.ui 文件上设置,以设置该文件的特定选项。这会覆盖 AUTOUIC_OPTIONS 目标属性中的选项。

目标可以通过 INTERFACE_AUTOUIC_OPTIONS 目标属性填充在调用 uic 时应使用的选项。这必须与依赖目标的 AUTOUIC_OPTIONS 目标属性内容一致。CMAKE_DEBUG_TARGET_PROPERTIES 变量可用于跟踪此类 INTERFACE_AUTOUIC_OPTIONS 的来源目标。这意味着提供 Qt 替代翻译系统的库可以指定在运行 uic 时应使用的选项

add_library(KI18n klocalizedstring.cpp)
target_link_libraries(KI18n Qt6::Core)

# KI18n uses the tr2i18n() function instead of tr().  That function is
# declared in the klocalizedstring.h header.
set(autouic_options
  -tr tr2i18n
  -include klocalizedstring.h
)

set_property(TARGET KI18n APPEND PROPERTY
  INTERFACE_AUTOUIC_OPTIONS ${autouic_options}
)

消耗项目链接到从上游导出的目标时,由于链接到 IMPORTED 目标,AUTOUIC 运行 uic 时会自动使用适当的选项

set(CMAKE_AUTOUIC ON)
# Uses a libwidget.ui file:
add_library(LibWidget libwidget.cpp)
target_link_libraries(LibWidget
  KF5::KI18n
  Qt5::Widgets
)

通过启用 SKIP_AUTOUIC 或更广泛的 SKIP_AUTOGEN,可以将源文件从 AUTOUIC 处理中排除。

AUTORCC

AUTORCC 目标属性控制 cmake(1) 是否创建规则,以便在适当的时候对后缀为 .qrc 的源文件执行 rcc

add_executable(myexe main.cpp resource_file.qrc)

通过设置 CMAKE_AUTORCC 变量,可以预设所有后续目标的 AUTORCC 目标属性。AUTORCC_OPTIONS 目标属性可以填充以设置传递给 rcc 的选项。可以填充 CMAKE_AUTORCC_OPTIONS 变量以预设所有后续目标的选项。AUTORCC_OPTIONS 源文件属性可以在 <name>.qrc 文件上设置,以设置该文件的特定选项。这会覆盖 AUTORCC_OPTIONS 目标属性中的选项。

通过启用 SKIP_AUTORCC 或更广泛的 SKIP_AUTOGEN,可以将源文件从 AUTORCC 处理中排除。

目标 <ORIGIN>_autogen

mocuic 工具作为 CMake 生成的合成 目标 <ORIGIN>_autogen 自定义目标 的一部分执行。默认情况下,该 目标 <ORIGIN>_autogen 目标继承 <ORIGIN> 目标的依赖项(参见 AUTOGEN_ORIGIN_DEPENDS)。可以通过将依赖项添加到 AUTOGEN_TARGET_DEPENDS 目标属性来向 目标 <ORIGIN>_autogen 目标添加依赖项。

注意

如果使用 Qt 5.15 或更高版本,且生成器为 NinjaMakefile 生成器,请参阅 目标 <ORIGIN>_autogen_timestamp_deps

目标 <ORIGIN>_autogen_timestamp_deps

如果使用 Qt 5.15 或更高版本,且生成器为 NinjaMakefile 生成器,则除了 目标 <ORIGIN>_autogen 目标之外,还会创建 <ORIGIN>_autogen_timestamp_deps 目标。此目标没有任何要执行的源或命令,但它具有以前由 Qt 5.15 之前的 目标 <ORIGIN>_autogen 目标继承的依赖项。这些依赖项将作为自定义命令的仅排序依赖项列表,而不会强制自定义命令重新执行。

Visual Studio 生成器

使用 Visual Studio 生成器 时,CMake 生成 PRE_BUILD 自定义命令 而不是 目标 <ORIGIN>_autogen 自定义目标(适用于 AUTOMOCAUTOUIC)。但这并非总是可能的,当以下情况之一发生时,会使用 目标 <ORIGIN>_autogen 自定义目标

Windows 上的 qtmain.lib

Qt 4 和 5 的 QtGui 库的 IMPORTED 目标指定 Qt 附带的 qtmain.lib 静态库将由所有启用了 WIN32_EXECUTABLE 的依赖可执行文件链接。

要禁用此行为,请为基于 Qt 5 的目标启用 Qt5_NO_LINK_QTMAIN 目标属性,或为基于 Qt 4 的目标启用 QT4_NO_LINK_QTMAIN 目标属性。

add_executable(myexe WIN32 main.cpp)
target_link_libraries(myexe Qt4::QtGui)

add_executable(myexe_no_qtmain WIN32 main_no_qtmain.cpp)
set_property(TARGET main_no_qtmain PROPERTY QT4_NO_LINK_QTMAIN ON)
target_link_libraries(main_no_qtmain Qt4::QtGui)