UNITY_BUILD¶
於 3.16 版本新增。
當此屬性設定為 true 時,目標原始碼檔案將會合併成批次以加快編譯速度。這是透過建立 (一組) 聯合原始碼來完成的,這些原始碼會 #include
原始原始碼,然後編譯這些聯合原始碼而不是原始原始碼。這被稱為 *Unity* 或 *Jumbo* 建置。
CMake 提供了不同的演算法來選擇哪些原始碼被分組到一個 *bucket* 中。演算法的選擇由 UNITY_BUILD_MODE
目標屬性決定,該屬性具有以下可接受的值
BATCH
在此模式下,CMake 決定哪些檔案被分組在一起。UNITY_BUILD_BATCH_SIZE
屬性控制每個聯合原始碼檔案可以組合的最大原始碼數量。GROUP
在此模式下,每個目標明確指定如何分組原始碼檔案。每個具有相同UNITY_GROUP
值的原始碼檔案將會分組在一起。任何沒有此屬性的原始碼都將會單獨編譯。當使用此模式時,UNITY_BUILD_BATCH_SIZE
屬性將會被忽略。
如果沒有明確指定 UNITY_BUILD_MODE
,CMake 將預設為 BATCH
。
以下語言支援聯合建置
C
於 3.16 版本新增。
CXX
於 3.16 版本新增。
CUDA
於 3.31 版本新增。
OBJC
於 3.29 版本新增。
OBJCXX
於 3.29 版本新增。
對於混合多種語言原始碼檔案的目標,CMake 會將語言分離,以便每個產生的聯合原始碼檔案只包含單一語言的原始碼。
當建立目標時,此屬性會由 CMAKE_UNITY_BUILD
變數的值初始化。
注意
專案不應直接將 UNITY_BUILD
屬性或其相關的 CMAKE_UNITY_BUILD
變數設定為 true。根據使用的建置機器和編譯器的功能,啟用聯合建置可能適當也可能不適當。因此,此功能應由開發人員控制,這通常是透過開發人員選擇是否在 CMAKE_UNITY_BUILD
變數上設定於 cmake(1)
命令列或某些其他等效方法。然而,如果已知為目標啟用聯合建置可能會導致問題,則**建議**將 UNITY_BUILD
目標屬性設定為 false。
ODR (單一定義規則) 錯誤¶
當多個原始碼檔案被包含到一個原始碼檔案中時,就像聯合建置所做的那樣,可能會導致 ODR 錯誤。CMake 提供了一些措施來幫助解決這些問題
任何具有非空
COMPILE_OPTIONS
、COMPILE_DEFINITIONS
、COMPILE_FLAGS
或INCLUDE_DIRECTORIES
來源屬性的原始碼檔案將不會合併到聯合來源中。任何透過
CXX_SCAN_FOR_MODULES
、CXX_SCAN_FOR_MODULES
或CXX_MODULES
檔案集成員資格掃描 C++ 模組來源的任何原始碼檔案都不會合併到聯合來源中。有關詳細資訊,請參閱cmake-cxxmodules(7)
。專案可以透過將其
SKIP_UNITY_BUILD_INCLUSION
來源屬性設定為 true 來防止單個原始碼檔案合併到聯合來源中。這可能是一種比為整個目標停用聯合建置更有效的方法,可以防止特定檔案出現問題。專案可以設定
UNITY_BUILD_UNIQUE_ID
來產生一個有效的 C 識別符,該識別符在聯合建置中每個檔案都是唯一的。這可以用於避免聯合建置中匿名命名空間的問題。UNITY_BUILD_CODE_BEFORE_INCLUDE
和UNITY_BUILD_CODE_AFTER_INCLUDE
目標屬性可用於在每個#include
語句之前和之後將程式碼注入到聯合原始碼檔案中。透過諸如
add_library()
、add_executable()
或target_sources()
等命令添加到目標的原始碼檔案的順序將會在產生的聯合原始碼檔案中保留。這可用於根據UNITY_BUILD_BATCH_SIZE
目標屬性來手動強制執行特定的分組。