AUTOMOC

目標是否應使用自動 moc 處理(適用於 Qt 專案)。

AUTOMOC 是一個布林值,用於指定 CMake 是否會自動處理 Qt moc 預處理器,也就是說,無需使用像 QT4_WRAP_CPP()qt5_wrap_cpp() 等命令。目前支援 Qt 版本 4 到 6。

此屬性會由 CMAKE_AUTOMOC 變數的值初始化,如果該變數在建立目標時已設定。

當此屬性設定為 ON 時,CMake 將在建置時掃描標頭檔和原始碼檔案,並相應地調用 moc

標頭檔處理

在組態時間,應由 AUTOMOC 掃描的標頭檔列表是從目標的原始碼計算而來。

  • 目標原始碼中的所有標頭檔都會加入掃描列表。

  • 對於目標原始碼中的所有 C++ 原始碼檔案 <source_base>.<source_extension>,CMake 會搜尋

    • 具有相同基本名稱的常規標頭 (<source_base>.<header_extension>) 和

    • 具有相同基本名稱和 _p 後綴的私有標頭 (<source_base>_p.<header_extension>)

    並將這些加入掃描列表。

在建置時,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++ 原始碼檔案,以尋找

如果找到 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> 是目標屬性 AUTOGEN_BUILD_DIR 的值。

include 目錄會自動新增至目標的 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_FILTERS:可以透過在此目標屬性中定義檔案名稱篩選器,從標頭或原始碼中提取 moc 相依性檔案名稱。

AUTOMOC_COMPILER_PREDEFINESmoc 的編譯器預先定義會寫入 moc_predefs.h 檔案。可以在此目標屬性中啟用或停用此檔案的產生。

SKIP_AUTOMOC:可以透過設定此原始碼檔案屬性,將原始碼和標頭檔從 AUTOMOC 處理中排除。

SKIP_AUTOGEN:可以透過設定此原始碼檔案屬性,將原始碼檔案從 AUTOMOCAUTOUICAUTORCC 處理中排除。

AUTOGEN_SOURCE_GROUP:可以使用此全域屬性將由 AUTOMOCAUTORCC 產生的檔案在 IDE 中分組,例如在 MSVS 中。

AUTOGEN_TARGETS_FOLDER:可以使用此全域屬性將 AUTOMOCAUTOUICAUTORCC 目標在 IDE 中分組,例如在 MSVS 中。

CMAKE_GLOBAL_AUTOGEN_TARGET:當此變數為 ON 時,將產生一個全域 autogen 目標,該目標依賴專案中所有由 AUTOMOCAUTOUIC 產生的 <ORIGIN>_autogen 目標 目標。

AUTOGEN_PARALLEL:此目標屬性控制在建置期間並行啟動的 mocuic 程序數量。

AUTOGEN_COMMAND_LINE_LENGTH_MAX:此目標屬性控制在 Windows 上何時使用回應檔案來處理 mocuic 程序的限制。

請參閱 cmake-qt(7) 手冊,以取得關於搭配 Qt 使用 CMake 的更多資訊。