UNITY_BUILD¶
3.16 版新增。
将此属性设置为 true 时,目标源文件将被合并成批次以加快编译速度。这是通过创建(一组)unity 源文件实现的,这些 unity 源文件 #include 了原始源文件,然后编译这些 unity 源文件而不是原始文件。这被称为Unity或Jumbo构建。
CMake 提供了不同的算法来选择哪些源文件被分组到存储桶中。算法选择由 UNITY_BUILD_MODE 目标属性决定,该属性具有以下可接受的值:
BATCH在此模式下,CMake 确定哪些文件被分组在一起。UNITY_BUILD_BATCH_SIZE属性控制每个 unity 源文件可以合并多少个源文件的上限。GROUP在此模式下,每个目标显式指定如何对源文件进行分组。具有相同UNITY_GROUP值的每个源文件将被分组在一起。任何不具有此属性的源文件都将单独编译。使用此模式时,会忽略UNITY_BUILD_BATCH_SIZE属性。
如果未指定显式的 UNITY_BUILD_MODE,CMake 将默认使用 BATCH。
Unity 构建支持以下语言:
C3.16 版新增。
CXX3.16 版新增。
CUDA在版本 3.31 中添加。
OBJC在版本 3.29 中添加。
OBJCXX在版本 3.29 中添加。
对于混合了多种语言的源文件的目标,CMake 会分离这些语言,以便每个生成的 unity 源文件只包含一种语言的源文件。
创建目标时,此属性由 CMAKE_UNITY_BUILD 变量的值初始化。
注意
项目不应直接将 UNITY_BUILD 属性或其关联的 CMAKE_UNITY_BUILD 变量设置为 true。根据所用构建机器和编译器的功能,启用 unity 构建可能合适,也可能不合适。因此,此功能应由开发人员控制,通常通过开发人员选择是否在 cmake(1) 命令或任何其他等效方法上设置 CMAKE_UNITY_BUILD 变量。但是,如果已知为目标启用 unity 构建可能导致问题,则建议将 UNITY_BUILD 目标属性设置为 false。
ODR(单一定义规则)错误¶
当多个源文件被包含到一个源文件中时,正如 unity 构建中所做的那样,这可能会导致 ODR 错误。CMake 提供了许多措施来帮助解决此类问题。
任何具有非空
COMPILE_OPTIONS、COMPILE_DEFINITIONS、COMPILE_FLAGS或INCLUDE_DIRECTORIES源属性的源文件不会被合并到 unity 源文件中。通过
CXX_SCAN_FOR_MODULES、CXX_SCAN_FOR_MODULES或属于CXX_MODULES文件集中的源文件,任何被扫描 C++ 模块源文件的源文件都不会被合并到 unity 源文件中。有关详细信息,请参阅cmake-cxxmodules(7)。项目可以通过将其
SKIP_UNITY_BUILD_INCLUSION源属性设置为 true,来阻止单个源文件被合并到 unity 源文件中。这比为整个目标禁用 unity 构建更能有效地防止特定文件出现问题。项目可以设置
UNITY_BUILD_UNIQUE_ID来生成一个有效的 C 标识符,该标识符在 unity 构建中对于每个文件都是唯一的。这可以用于避免 unity 构建中匿名命名空间的问题。可以使用
UNITY_BUILD_CODE_BEFORE_INCLUDE和UNITY_BUILD_CODE_AFTER_INCLUDE目标属性在每个#include语句之前和之后注入代码到 unity 源文件中。通过
add_library()、add_executable()或target_sources()等命令添加到目标的源文件的顺序将保留在生成的 unity 源文件中。这可以用于根据UNITY_BUILD_BATCH_SIZE目标属性手动强制执行特定的分组。