CMP0114

3.19 版本新增。

ExternalProject 步骤目标完全采纳其步骤。

``ExternalProject_Add()`` 的 ``STEP_TARGETS`` 选项,以及 ``ExternalProject_Add_StepTargets()`` 函数,可用于为外部项目的各个步骤创建构建目标。

在 CMake 3.18 及更早版本中,步骤目标存在一些限制

  • 步骤目标始终依赖于 ``ExternalProject_Add()`` 的 ``DEPENDS`` 选项命名的目标,尽管并非所有步骤都需要它们。为了允许在没有这些依赖的情况下创建步骤目标,可以使用 ``ExternalProject_Add()`` 的 ``INDEPENDENT_STEP_TARGETS`` 选项或 ``ExternalProject_Add_StepTargets()`` 的 ``NO_DEPENDS`` 选项。然而,添加此类“独立”步骤目标仅对特定步骤有意义,例如 ``download``、``update`` 和 ``patch``,因为它们不需要外部项目的任何构建依赖。此外,为依赖于非独立步骤的步骤创建独立步骤目标没有意义。这些规则未强制执行,不遵循这些规则的项目可能会生成行为混乱且依赖于生成器的构建系统。

  • 步骤目标持有实现其步骤的自定义命令的副本,这些副本与 ``ExternalProject_Add()`` 创建的主目标中的副本分开,并且主目标不依赖于步骤目标。在并行构建中同时驱动主目标和步骤目标时,步骤命令的多个副本可能会并行运行并相互竞争。

    此外,在策略 CMP0113 之前,由 Makefile Generators 生成的步骤目标也包含其步骤所依赖的所有自定义命令。这可能导致即使在串行构建中,这些步骤也会被重复执行。

在 CMake 3.19 及更高版本中,``ExternalProject`` 模块倾向于采用一种改进的设计来解决这些问题

  • 每个步骤都被归类为“独立”,如果它不依赖于 ``ExternalProject_Add()`` 的 ``DEPENDS`` 选项命名的其他目标。预定义步骤默认自动分类

    • ``download``、``update`` 和 ``patch`` 步骤是独立的。

    • ``configure``、``build``、``test`` 和 ``install`` 步骤不是独立的。

    对于自定义步骤,``ExternalProject_Add_Step()`` 命令提供了一个 ``INDEPENDENT`` 选项来将其标记为独立。如果一个步骤依赖于其他非独立步骤,则将其标记为独立是错误的。请注意,此处“独立”一词的用法仅指独立于外部目标,并且与其依赖于其他步骤的依赖性无关。

  • 通过 ``ExternalProject_Add()`` 的 ``STEP_TARGETS`` 选项或 ``ExternalProject_Add_Step()`` 函数创建的步骤目标,当且仅当其步骤被标记为独立时,它们才被认为是独立的。``ExternalProject_Add()`` 的 ``INDEPENDENT_STEP_TARGETS`` 选项和 ``ExternalProject_Add_StepTargets()`` 的 ``NO_DEPENDS`` 选项不再允许使用。

  • 步骤目标在创建时,完全负责持有实现其步骤的自定义命令。``ExternalProject_Add()`` 创建的主目标依赖于步骤目标,而步骤目标之间也相互依赖。目标级别的依赖关系与每个步骤的自定义命令所使用的文件级别的依赖关系相匹配。

    当使用 ``ExternalProject_Add()`` 的 ``UPDATE_DISCONNECTED`` 或 ``TEST_EXCLUDE_FROM_MAIN`` 选项,或者对自定义步骤使用 ``ExternalProject_Add_Step()`` 的 ``EXCLUDE_FROM_MAIN`` 选项时,可能会自动创建一些步骤目标。这些是必需的,用于承载主目标和断开连接的步骤目标通常依赖的步骤。

策略 ``CMP0114`` 为尚未更新以期望新行为的项目提供了兼容性。此策略的 ``OLD`` 行为是使用 3.18 及更早版本中记录的行为。此策略的 ``NEW`` 行为是使用 3.19 及更高版本中推荐的行为。

此策略在 CMake 版本 3.19 中引入。它可以通过 cmake_policy()cmake_minimum_required() 设置。如果未设置,CMake 会发出警告并使用 OLD 行为。

注意

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