统一构建¶
在 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 构建。 CMake 版本 |发布|支持合并``C`` 和``CXX`` 源文件。对于混合来自多种语言的源文件的目标,CMake 将分离语言,以便每个生成的统一源文件仅包含一种语言的源代码。
创建目标时,此属性由 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 源属性的源文件都不会合并到统一源中。
项目可以通过将其
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目标属性手动实施特定分组。