cmake-cxxmodules(7)¶
在版本 3.28 中新增。
C++ 20 在語言中引入了「模組」的概念。此設計要求建置系統對編譯進行排序,以可靠地滿足 import
陳述式。CMake 的實作要求編譯器在建置期間掃描原始檔以查找模組依賴關係,整理掃描結果以推斷排序約束,並告知建置工具如何動態更新建置圖。
編譯策略¶
使用 C++ 模組,編譯一組 C++ 原始碼不再是完全並行的。也就是說,任何給定的原始碼可能首先需要先編譯另一個原始檔,以便提供「CMI」(已編譯模組介面)或「BMI」(二進制模組介面),C++ 編譯器使用它們來滿足其他原始碼中的 import
陳述式。使用標頭檔,原始碼可以共享其宣告,以便任何消費者都可以獨立編譯。使用模組,宣告現在由編譯器根據原始檔的內容及其 export
陳述式在編譯期間產生到這些 BMI 檔案中。
編譯所需的順序需要建置時解析排序,因為順序由原始碼的內容控制。這表示需要從建置期間的原始碼中提取排序,以避免為每個原始碼變更重新產生建置圖,透過組態和產生階段來獲得正確的建置。
一般策略是使用「掃描器」來提取排序依賴資訊,並透過取得每個原始碼的掃描結果(以 P1689R5 檔案表示)並「整理」目標內以及目標可見的目標產生的模組的依賴關係,來更新現有邊緣之間的新邊緣的建置圖。主要任務是產生「模組映射」檔案,並將 BMI 的路徑傳遞給每個編譯規則,以滿足 import
陳述式。整理器還具有使用建置時資訊來填寫資訊的任務,包括模組介面單元、其 BMI 以及任何匯出具有 C++ 模組的目標的屬性的 install
規則。
注意
CMake 專注於正確的建置,然後才考慮效能改進。在選擇的策略中,有一些已知的策略可能會提高建置效能。但是,它們被延遲到我們有一個可運作的模型可以與之比較。同樣重要的是要注意,在某種情況下(例如,乾淨的建置)有用的策略可能在不同的情況下(例如,增量建置)沒有效能。找到平衡並提供控制來選擇策略是未來的任務。
掃描控制¶
是否掃描原始碼以查找 C++ 模組的使用情況取決於以下查詢。將使用第一個提供是/否答案的查詢。
如果原始檔屬於
CXX_MODULES
類型的檔案集,則將掃描它。如果目標未使用至少 C++ 20,則不會掃描它。
如果原始檔不是
CXX
語言,則不會掃描它。如果設定了
CXX_SCAN_FOR_MODULES
原始檔屬性,則將使用其值。如果設定了
CXX_SCAN_FOR_MODULES
目標屬性,則將使用其值。設定CMAKE_CXX_SCAN_FOR_MODULES
變數以在建立所有目標時初始化此屬性。否則,如果編譯器和產生器支援掃描,則將掃描原始檔。請參閱政策
CMP0155
。
請注意,任何掃描的原始碼都將從任何 Unity 建置中排除(請參閱 UNITY_BUILD
),因為模組相關的陳述式只能在 C++ 翻譯單元中的一個位置發生。
編譯器支援¶
CMake 原生支援模組依賴掃描的編譯器包括
MSVC 工具組 14.34 及更新版本(隨附於 Visual Studio 17.4 及更新版本)
LLVM/Clang 16.0 及更新版本
GCC 14(適用於開發中分支,在 2023-09-20 之後)及更新版本
import std
支援¶
對 import std
的支援僅限於以下工具鏈和標準函式庫組合
Clang 18.1.2 及更新版本,搭配
-stdlib=libc++
MSVC 工具組 14.36 及更新版本(隨附於 Visual Studio 17.6 Preview 2 及更新版本)
可以使用 CMAKE_CXX_COMPILER_IMPORT_STD
變數來偵測作用中 C++ 工具鏈對標準層級的支援。
注意
僅當透過 CMAKE_EXPERIMENTAL_CXX_IMPORT_STD
gate 啟用對 import std;
的實驗性支援時,才會提供此支援。
產生器支援¶
支援掃描原始碼以查找 C++ 模組的產生器列表包括
限制¶
目前 CMake 中的 C++ 模組支援存在許多已知的限制。這不包含編譯器中已知的限制或錯誤,因為這些限制或錯誤可能會隨時間而改變。
適用於所有產生器
不支援標頭單元。
沒有對
import std;
或其他編譯器提供的模組的內建支援。
適用於 Ninja 產生器
需要
ninja
1.11 或更新版本。
僅限 Visual Studio 2022 和 MSVC 工具組 14.34 (Visual Studio 17.4) 及更新版本。
不支援匯出或安裝 BMI 或模組資訊。
不支援從具有 C++ 模組的
IMPORTED
目標編譯 BMI(包括import std
)。無法診斷從
PUBLIC
模組來源使用PRIVATE
來源提供的模組。