奥托莫克

是否应使用 auto-moc 处理目标(对于 Qt 项目)。

AUTOMOC 是一个布尔值,指定 CMake 是否会自动处理 Qt moc 预处理器,即不必使用像 QT4_WRAP_CPP(), QT5_WRAP_CPP(), etc. 目前,支持 Qt 版本 4 到 6。

如果在创建目标时设置了此属性,则该属性由 CMAKE_AUTOMOC 变量的值初始化。

当此属性设置为“ON”时,CMake 将在构建时扫描头文件和源文件并相应地调用“moc”。

头文件处理

在配置时,应由“AUTOMOC”扫描的头文件列表是根据目标源计算的。

  • 目标源中的所有头文件都添加到扫描列表中。

  • 对于目标源中的所有 C++ 源文件 <source_base>.<source_extension>,CMake 搜索

    • 具有相同基本名称的常规标头(<source_base>.<header_extention>)和

    • 具有相同基本名称和 _p 后缀的私有标头 (<source_base>_p.<header_extention>)

    并将它们添加到扫描列表中。

在构建时,CMake 从列表中扫描每个未知的或修改过的头文件并搜索

  • 来自 AUTOMOC_MACRO_NAMES 的 Qt 宏,

  • 来自 Q_PLUGIN_METADATA 宏的 FILE 参数的附加文件依赖项和

  • 由 AUTOMOC_DEPEND_FILTERS 中定义的过滤器检测到的附加文件依赖项。

如果找到 Qt 宏,则头文件将由 moc 编译为输出文件 moc_<base_name>.cpp。完整的输出文件路径在“输出文件位置”一节中进行了描述。

如果附加文件依赖项中的文件发生更改,则标头将再次编译“moc”。

头文件 moc 输出文件 moc_<base_name>.cpp 可以包含在源文件中。在“在源代码中包含头文件 moc”一节中,有关于该主题的更多信息。

源文件处理

在构建时,CMake 从目标源中扫描每个未知或修改过的 C++ 源文件以查找

  • 来自 AUTOMOC_MACRO_NAMES 的 Qt 宏,

  • 包含头``moc``文件(参见`在源中包含头moc文件`_),

  • 来自 Q_PLUGIN_METADATA 宏的 FILE 参数的附加文件依赖项和

  • 由 AUTOMOC_DEPEND_FILTERS 中定义的过滤器检测到的附加文件依赖项。

如果找到 Qt 宏,则 C++ 源文件“<base>.<source_extension>”也应该包含一个 include 语句

#include <<base>.moc> // or
#include "<base>.moc"

然后源文件将由 moc 编译为输出文件 <base>.moc。完整输出文件路径的描述在“输出文件位置”部分。

如果附加文件依赖项中的文件发生更改,源代码将再次编译“moc”。

在源代码中包含标题 moc 文件

源文件可以通过使用形式的 include 语句来包含标头 <header_base>.<header_extension> 的``moc`` 输出文件

#include <moc_<header_base>.cpp> // or
#include "moc_<header_base>.cpp"

如果头文件的 moc 输出文件被源包含,它将在与未包含时不同的位置生成。这在“输出文件位置”部分中有描述。

输出文件位置

包括 moc 输出文件

源文件包含的``moc``输出文件将在

  • <AUTOGEN_BUILD_DIR>/include 用于单个配置生成器或在

  • <AUTOGEN_BUILD_DIR>/include_<CONFIG> 用于 多配置 生成器。

其中``<AUTOGEN_BUILD_DIR>`` 是目标属性的值:prop_tgt:AUTOGEN_BUILD_DIR

包含目录会自动添加到目标的 INCLUDE_DIRECTORIES

不包括 moc 输出文件

未包含在源文件中的``moc``输出文件将生成

  • <AUTOGEN_BUILD_DIR>/<SOURCE_DIR_CHECKSUM> 用于单个配置生成器或在,

  • <AUTOGEN_BUILD_DIR>/include_<CONFIG>/<SOURCE_DIR_CHECKSUM> 用于 多配置 生成器。

其中``<SOURCE_DIR_CHECKSUM>``是根据``moc``输入文件的相对父目录路径计算的校验和。该方案允许在不同目录中具有相同名称的 moc 输入文件。

所有未包含的 moc 输出文件将由 CMake 生成的文件自动包含

  • <AUTOGEN_BUILD_DIR>/mocs_compilation.cpp,或者

  • <AUTOGEN_BUILD_DIR>/mocs_compilation_$<CONFIG>.cpp,

它被添加到目标的源中。

Qt版本检测

AUTOMOC 启用的目标需要知道他们正在使用的 Qt 主要和次要版本。主要版本通常由目标链接到的``Qt [456] Core``库的``INTERFACE_QT_MAJOR_VERSION``属性提供。为了找到次要版本,CMake 构建了一个可用的 Qt 版本列表

  • Qt6Core_VERSION_MAJORQt6Core_VERSION_MINOR 变量(通常由 find_package(Qt6...) 设置)

  • Qt6Core_VERSION_MAJORQt6Core_VERSION_MINOR 目录属性

  • Qt5Core_VERSION_MAJORQt5Core_VERSION_MINOR 变量(通常由 find_package(Qt5...) 设置)

  • Qt5Core_VERSION_MAJORQt5Core_VERSION_MINOR 目录属性

  • QT_VERSION_MAJORQT_VERSION_MINOR 变量(通常由 find_package(Qt4...) 设置)

  • QT_VERSION_MAJORQT_VERSION_MINOR 目录属性

add_executable()add_library() 调用的上下文中。

假设 INTERFACE_QT_MAJOR_VERSION 是一个有效的数字,列表中的第一个条目与匹配的主要版本被采用。如果未找到匹配的主要版本,则会生成错误。如果 INTERFACE_QT_MAJOR_VERSION 不是有效数字,则采用列表中的第一个条目。

find_package(Qt[456]...) 调用设置了 QT/Qt[56]Core_VERSION_MAJOR/MINOR 变量。如果调用与 add_executable()add_library() 调用处于不同的上下文中,例如在函数中,则版本变量可能无法用于启用“AUTOMOC”的目标。在那种情况下,版本变量可以从``find_package(Qt[456]...)`` 调用上下文转发到 add_executable()add_library() 调用上下文作为目录属性。以下 Qt5 示例演示了该过程。

function (add_qt5_client)
  find_package(Qt5 REQUIRED QUIET COMPONENTS Core Widgets)
  ...
  set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
    PROPERTY Qt5Core_VERSION_MAJOR "${Qt5Core_VERSION_MAJOR}")
  set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
    PROPERTY Qt5Core_VERSION_MINOR "${Qt5Core_VERSION_MAJOR}")
  ...
endfunction ()
...
add_qt5_client()
add_executable(myTarget main.cpp)
target_link_libraries(myTarget Qt5::QtWidgets)
set_property(TARGET myTarget PROPERTY AUTOMOC ON)

修饰符

AUTOMOC_EXECUTABLEmoc 可执行文件将被自动检测,但可以使用此目标属性强制为某个二进制文件。

AUTOMOC_MOC_OPTIONS:可以在此目标属性中设置 moc 的其他命令行选项。

AUTOMOC_MACRO_NAMES:可以扩展此 Qt 宏名称列表以在标头和源中搜索其他宏。

AUTOMOC_DEPEND_FILTERSmoc 依赖文件名可以通过在此目标属性中定义文件名过滤器从标头或源中提取。

AUTOMOC_COMPILER_PREDEFINESmoc 的编译器预定义被写入 moc_predefs.h 文件。可以在此目标属性中启用或禁用此文件的生成。

SKIP_AUTOMOC:通过设置此源文件属性,可以从``AUTOMOC`` 处理中排除源和标头。

SKIP_AUTOGEN:通过设置此源文件属性,源文件可以从 AUTOMOCAUTOUICAUTORCC 处理中排除。

AUTOGEN_SOURCE_GROUP:此全局属性可用于在 IDE 中将由 AUTOMOCAUTORCC 生成的文件分组在一起,例如在 MSVS 中。

AUTOGEN_TARGETS_FOLDER:此全局属性可用于在 IDE 中将 AUTOMOCAUTOUICAUTORCC 目标组合在一起,例如在 MSVS 中。

CMAKE_GLOBAL_AUTOGEN_TARGET: 一个全局的``autogen`` 目标,它依赖于项目中所有``AUTOMOC`` 或 AUTOUIC 生成的``<ORIGIN>_autogen`` 目标,将在以下时间生成这个变量是 ON

AUTOGEN_PARALLEL:此目标属性控制在构建期间并行启动的 mocuic 进程的数量。

有关在 Qt 中使用 CMake 的更多信息,请参阅 cmake-qt(7) 手册。