UNITY_BUILD¶
在 3.16 版本中加入。
当此属性设置为 true 时,目标源文件将被合并成批次以加快编译速度。这是通过创建(一组)统一源文件来完成的,这些文件 #include
原始源文件,然后编译这些统一源文件而不是原始源文件。这被称为 Unity 或 Jumbo 构建。
CMake 提供了不同的算法来选择哪些源文件被分组到一个桶中。算法选择由 UNITY_BUILD_MODE
目标属性决定,该属性具有以下可接受的值
BATCH
在此模式下,CMake 确定哪些文件被分组在一起。UNITY_BUILD_BATCH_SIZE
属性控制每个统一源文件可以合并的源文件数量上限。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 会分离语言,以便每个生成的统一源文件仅包含单一语言的源文件。
此属性由创建目标时 CMAKE_UNITY_BUILD
变量的值初始化。
注意
项目不应直接将 UNITY_BUILD
属性或其关联的 CMAKE_UNITY_BUILD
变量设置为 true。根据构建机器和所用编译器的能力,启用 unity 构建可能合适,也可能不合适。因此,此功能应由开发者控制,通常通过开发者选择是否在 CMAKE_UNITY_BUILD
变量在 cmake(1)
命令行或一些其他等效方法中设置来完成。但是,如果已知为目标启用 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
目标属性手动强制执行特定的分组。