cmake_policy

管理 CMake 策略设置。有关已定义策略的信息,请参阅 cmake-policies(7) 手册。

随着 CMake 的发展,有时为了修复错误或改进现有功能的实现,需要更改现有行为。CMake 策略机制旨在帮助现有项目在 CMake 新版本引入行为更改时继续构建。每个新策略(行为更改)都带有一个形如 CMP<NNNN> 的标识符,其中 <NNNN> 是一个整数索引。与每个策略相关的文档描述了 OLDNEW 行为以及引入策略的原因。项目可以设置每个策略以选择所需的行为。当 CMake 需要知道要使用哪种行为时,它会检查项目指定的设置。如果没有可用的设置,则假定为 OLD 行为并产生警告,要求设置该策略。

按 CMake 版本设置策略

cmake_policy 命令用于将策略设置为 OLDNEW 行为。虽然支持单独设置策略,但我们鼓励项目根据 CMake 版本设置策略

cmake_policy(VERSION <min>[...<max>])

版本 3.12 新增: 可选的 <max> 版本。

<min> 和可选的 <max> 都是形式为 major.minor[.patch[.tweak]] 的 CMake 版本,... 是字面量。 <min> 版本必须至少为 2.4 且不大于当前运行的 CMake 版本。如果指定了 <max> 版本,则必须至少为 <min> 版本,但可以超过当前运行的 CMake 版本。如果当前运行的 CMake 版本早于 3.12,则额外的 ... 点将被视为版本组件分隔符,导致 ...<max> 部分被忽略,并保留 3.12 之前基于 <min> 的策略行为。

这指定当前 CMake 代码是为给定范围的 CMake 版本 <min>[...<max>] 编写的。它将“策略版本”设置为

  • 该范围的 <max> 版本(如果已指定),或者

  • <min> 版本,或者

  • 如果 CMAKE_POLICY_VERSION_MINIMUM 变量的值高于前两个版本,则设置为该变量的值。

策略版本有效地请求特定 CMake 版本偏好的行为,并告知较新的 CMake 版本要针对其新策略发出警告。运行中的 CMake 版本已知的所有策略以及在该版本或更早版本中引入的所有策略都将设置为使用 NEW 行为。在后续版本中引入的所有策略都将未设置(除非 CMAKE_POLICY_DEFAULT_CMP<NNNN> 变量设置了默认值)。这有效地请求特定 CMake 版本偏好的行为,并告知较新的 CMake 版本要针对其新策略发出警告。

请注意,cmake_minimum_required(VERSION) 命令也隐式调用 cmake_policy(VERSION)

版本 4.0 更改: 与 CMake 3.5 之前版本的兼容性已移除。未将 3.5 或更高版本指定为其策略版本(可选通过 ...<max>)的 cmake_minimum_required(VERSION)cmake_policy(VERSION) 调用将在 CMake 4.0 及更高版本中产生错误。

版本 3.31 更改: 与 CMake 3.10 之前版本的兼容性已被弃用。未将 3.10 或更高版本指定为其策略版本(可选通过 ...<max>)的 cmake_minimum_required(VERSION)cmake_policy(VERSION) 调用将在 CMake 3.31 及更高版本中产生弃用警告。

版本 3.27 更改: 与 CMake 3.5 之前版本的兼容性已被弃用。未将 3.5 或更高版本指定为其策略版本(可选通过 ...<max>)的 cmake_minimum_required(VERSION)cmake_policy(VERSION) 调用将在 CMake 3.27 及更高版本中产生弃用警告。

版本 3.19 更改: 与 CMake 2.8.12 之前版本的兼容性已被弃用。未将 2.8.12 或更高版本指定为其策略版本(可选通过 ...<max>)的 cmake_minimum_required(VERSION)cmake_policy(VERSION) 调用将在 CMake 3.19 及更高版本中产生弃用警告。

显式设置策略

cmake_policy(SET CMP<NNNN> NEW|OLD)

告诉 CMake 对给定策略使用 OLDNEW 行为。依赖于给定策略的旧行为的项目可以通过将策略状态设置为 OLD 来抑制策略警告。或者,可以修复项目以与新行为一起工作,并将策略状态设置为 NEW

注意

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

检查策略设置

cmake_policy(GET CMP<NNNN> <variable>)

检查给定策略是设置为 OLD 还是 NEW 行为。如果策略已设置,输出 <variable> 值将为 OLDNEW,否则为空。

CMake 策略栈

CMake 将策略设置保存在一个栈上,因此 cmake_policy 命令所做的更改仅影响栈顶。CMake 会为每个子目录自动管理策略栈上的一个新条目,以保护其父级和同级。CMake 还会为通过 include()find_package() 命令加载的脚本管理一个新条目,除非调用时带有 NO_POLICY_SCOPE 选项(另请参阅策略 CMP0011)。cmake_policy 命令提供了一个接口来管理策略栈上的自定义条目

cmake_policy(PUSH)

在策略栈上创建一个新条目。

cmake_policy(POP)

移除使用 cmake_policy(PUSH) 创建的最后一个策略栈条目。

每个 PUSH 都必须有一个匹配的 POP 来清除任何更改。这对于临时更改策略设置很有用。对 cmake_minimum_required(VERSION)cmake_policy(VERSION)cmake_policy(SET) 命令的调用仅影响策略栈的当前顶部。

版本 3.25 新增: block(SCOPE_FOR POLICIES) 命令提供了一种更灵活、更安全的方式来管理策略栈。当离开块范围时,pop 操作会自动完成,因此无需在每个 return() 之前调用 cmake_policy(POP)

# stack management with cmake_policy()
function(my_func)
  cmake_policy(PUSH)
  cmake_policy(SET ...)
  if (<cond1>)
    ...
    cmake_policy(POP)
    return()
  elseif(<cond2>)
    ...
    cmake_policy(POP)
    return()
  endif()
  ...
  cmake_policy(POP)
endfunction()

# stack management with block()/endblock()
function(my_func)
  block(SCOPE_FOR POLICIES)
    cmake_policy(SET ...)
    if (<cond1>)
      ...
      return()
    elseif(<cond2>)
      ...
      return()
    endif()
    ...
  endblock()
endfunction()

通过 function()macro() 命令创建的命令在创建时会记录策略设置,并在调用时使用预记录的策略。如果函数或宏实现设置了策略,则更改会自动向上传播,直到到达最近的嵌套策略栈条目。

另请参阅