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