cmake_policy

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

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

按 CMake 版本设置策略

cmake_policy 命令用于将策略设置为``OLD`` 或``NEW`` 行为。虽然支持单独设置策略,但我们鼓励项目根据 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 版本编写的。 CMake 的运行版本已知并在“<min>”(或“<max>”,如果指定)版本或更早版本中引入的所有策略都将设置为使用“NEW”行为。以后版本中引入的所有策略都将被取消设置(除非 CMAKE_POLICY_DEFAULT_CMP<NNNN> 变量设置了默认值)。这有效地请求了给定 CMake 版本的首选行为,并告诉较新的 CMake 版本警告他们的新政策。

请注意 cmake_minimum_required(VERSION) 命令也隐式调用了``cmake_policy(VERSION)``。

显式设置策略

cmake_policy(SET CMP<NNNN> NEW)
cmake_policy(SET CMP<NNNN> OLD)

告诉 CMake 对给定策略使用“旧”或“新”行为。依赖于给定策略的旧行为的项目可能会通过将策略状态设置为“旧”来消除策略警告。或者,可以修复项目以使用新行为并将策略状态设置为“NEW”。

备注

策略的“旧”行为是 :manual:根据定义 <cmake-policies(7)> 已弃用,并且可能会在未来版本的 CMake 中删除。

检查策略设置

cmake_policy(GET CMP<NNNN> <variable>)

检查给定的策略是否设置为“旧”或“新”行为。如果设置了策略,则输出“<variable>”值将为“OLD”或“NEW”,否则为空。

CMake 策略堆栈

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

cmake_policy(PUSH)
cmake_policy(POP)

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

在 3.25 版本加入: block()endblock() 命令提供了一种更灵活、更安全的方式来管理策略堆栈。 pop 操作是在执行 endblock() 命令时自动完成的,因此它避免在每个 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() 命令创建的命令在创建时记录策略设置,并在调用时使用预记录策略。如果函数或宏实现设置了策略,更改会自动向上传播到调用者,直到它们到达最近的嵌套策略堆栈条目。

也可以看看