UNITY_BUILD¶
在版本 3.16 中添加。
当此属性设置为 true 时,目标源文件会被合并到批次中以实现更快的编译。这是通过创建一(组)将包含原始源的 unity 源文件完成的,然后编译这些 unity 源文件而不是原始源文件。这被称为“Unity”或“Jumbo”编译。
CMake 提供了不同的算法来选择哪些源被分组到“bucket”中。算法选择由 UNITY_BUILD_MODE
目标属性来确定,该属性具有以下可接受值
BATCH
当在此模式下时,CMake 确定哪些文件分组在一起。UNITY_BUILD_BATCH_SIZE
属性控制每个 unity 源文件中可以合并的源总数上限。GROUP
当在此模式下时,每个目标明确指定如何对源文件进行分组。具有相同UNITY_GROUP
值的每个源文件会被分组在一起。任何不具有此属性的源文件都会单独编译。当使用此模式时,会忽略UNITY_BUILD_BATCH_SIZE
属性。
如果未明确指定 UNITY_BUILD_MODE
,CMake 会默认为 BATCH
。
Unity 编译支持以下语言
C
在版本 3.16 中添加。
CXX
在版本 3.16 中添加。
CUDA
在版本 3.31 中添加。
OBJC
在版本 3.29 中添加。
OBJCXX
在版本 3.29 中添加。
对于来自多个语言的源文件混合的目标,CMake 会对语言进行分离,从而使每个生成的 unity 源文件只包含一种语言的源文件。
当创建目标时,此属性由 CMAKE_UNITY_BUILD
变量的值初始化。
注意
项目不应该直接设置 UNITY_BUILD
属性或其关联的 CMAKE_UNITY_BUILD
为 true。根据所用构建机器和编译器不同,启用合并构建可能不合适。因此,该功能应当由开发人员控制,即,通常是通过开发人员选择是否在 cmake(1)
命令行或其他等效方法中设置 CMAKE_UNITY_BUILD
变量来完成。但是,如果确定对目标启用合并构建会导致问题,则建议将 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
目标属性来手动强制执行特定的分组。