CMP0168

3.30 版本新增。

FetchContent 模块直接实现步骤,而不再通过子构建(sub-build)实现。

CMake 3.29 及以下版本将 FetchContent 实现为单独的子构建。这需要配置该单独的项目并使用构建工具。对于某些生成器和操作系统,这种方法可能非常缓慢。CMake 3.30 及以上版本倾向于将下载、更新和补丁步骤作为主项目的一部分直接实现。

NEW 行为具有以下特征

  • 不使用子构建。所有操作均直接在主项目的 CMake 配置步骤中实现。在 CMake 脚本模式下运行时,无需构建工具。

  • 不支持生成器表达式和 $(SOMEVAR) 形式的 GNU Make 变量。它们不应在 FetchContent_Declare()FetchContent_Populate() 的任何参数中使用。

  • 所有 LOG_...USES_TERMINAL_... 选项、QUIET 选项以及 FETCHCONTENT_QUIET 变量均被忽略。FetchContent 的输出始终是主项目配置输出的一部分。这也意味着它现在遵循消息日志级别(请参阅 CMAKE_MESSAGE_LOG_LEVEL--log-level)。默认的消息日志级别应与使用 OLD 策略设置时的 QUIET 相当,区别在于现在会显示警告。

  • PREFIXTMP_DIRSTAMP_DIRLOG_DIRDOWNLOAD_DIR 选项及其关联的目录属性均被忽略。FetchContent 模块在内部控制这些位置。

  • cmake --fresh 将删除用于跟踪和填充依赖项的戳记(stamp)和脚本文件。这将强制重新执行依赖项的下载、更新和补丁步骤。cmake --fresh 不会影响用于下载的目录,因此对于 URL 下载方法,之前下载的任何文件仍可重复使用。

OLD 行为具有以下特征

  • 始终使用子构建来实现下载、更新和补丁步骤。即使在 CMake 脚本模式下使用 FetchContent_Populate(),也必须具备构建工具。

  • 可以使用生成器表达式和 $(SOMEVAR) 形式的 GNU Make 变量,尽管这种用法几乎总是不合适的。它们在子构建中被评估,因此无法看到来自主构建的任何信息。

  • 支持与下载、更新或补丁步骤相关的所有日志记录、终端控制和目录选项。

  • 如果使用了 QUIET 选项,或者 FETCHCONTENT_QUIET 变量被设置为 true,则输出中不会显示警告。

  • cmake --fresh 对依赖项的戳记或脚本文件没有影响。之前执行的步骤仅在有关依赖项的详细信息发生更改时才会重新运行。

用户很有可能将 CMAKE_POLICY_DEFAULT_CMP0168 变量设置为 NEW,从而全局切换到 NEW 行为,同时等待项目及其依赖项更新为默认使用 NEW 策略设置。项目通常不会使用 NEW 行为不再支持的特性,即使是那些使用了这些特性的项目,在忽略这些选项时往往也能正常工作。在全局设置此行为之前,请检查是否有任何 FetchContent_Declare()FetchContent_Populate() 调用以会改变可观察行为的方式使用了被忽略的选项(将临时文件或内部生成的文件放在不同位置除外)。

此策略引入于 CMake 版本 3.30。它可以通过 cmake_policy()cmake_minimum_required() 设置。如果未设置,CMake *不会* 警告,并使用 OLD 行为。

注意

策略的 OLD 行为根据定义已被弃用,并可能在未来版本的 CMake 中被移除。