cmake_policy¶
管理 CMake 策略设置。有关已定义策略的信息,请参阅 cmake-policies(7) 手册。
随着 CMake 的发展,有时为了修复错误或改进现有功能的实现,必须改变现有的行为。CMake 策略机制旨在帮助确保现有项目在 CMake 引入行为变更的新版本中仍能构建。每个新策略(行为变更)都会被赋予一个 CMP<NNNN> 形式的标识符,其中 <NNNN> 是一个整数索引。与每个策略关联的文档描述了 OLD(旧)和 NEW(新)行为以及引入该策略的原因。项目可以设置每个策略以选择期望的行为。当 CMake 需要知道使用哪种行为时,它会检查项目指定的设置。如果没有任何设置,则默认采用 OLD 行为,并产生一条警告,要求设置该策略。
按 CMake 版本设置策略¶
cmake_policy 命令用于将策略设置为 OLD 或 NEW 行为。虽然支持单独设置策略,但我们鼓励项目根据 CMake 版本来设置策略。
- cmake_policy(VERSION <min>[...<policy_max>])¶
3.12 版本新增: 可选的 <policy_max> 版本。
<min> 和可选的 <policy_max> 均为 major.minor[.patch[.tweak]] 形式的 CMake 版本号,且 ... 是字面量。<min> 版本必须至少为 2.4,且不得超过运行中的 CMake 版本。<policy_max> 版本(如果指定)必须至少为 <min> 版本,但可以超过运行中的 CMake 版本。如果运行的 CMake 版本低于 3.12,额外的 ... 点将被视为版本组件分隔符,导致 ...<policy_max> 部分被忽略,并保留 3.12 版本之前基于 <min> 的策略行为。
这指定了当前的 CMake 代码是为给定的 CMake 版本范围 <min>[...<policy_max>] 编写的。它将“策略版本”设置为:
如果指定了范围的
<policy_max>版本,则设置为该版本;或者设置为
<min>版本;或者如果
CMAKE_POLICY_VERSION_MINIMUM变量的值高于前两个版本,则设置为该变量值。
策略版本有效地请求了给定 CMake 版本所偏好的行为,并告知较新的 CMake 版本对它们的新策略发出警告。所有运行中的 CMake 版本已知且在策略版本或更早版本中引入的策略都将被设置为使用 NEW 行为。在后续版本中引入的所有策略都将保持未设置状态(除非 CMAKE_POLICY_DEFAULT_CMP<NNNN> 变量设置了默认值)。
注意
...<policy_max> 并不意味着禁止使用更高版本的 CMake。它仅指定了该项目或模块已进行过主动更新和维护的最高 CMake 版本。
请注意,cmake_minimum_required(VERSION) 命令也会隐式调用 cmake_policy(VERSION)。
4.0 版本变更: 移除了对 3.5 之前版本 CMake 的兼容性。在 CMake 4.0 及以上版本中,调用未指定至少 3.5 作为其策略版本(可通过 ...<policy_max> 可选指定)的 cmake_minimum_required(VERSION) 或 cmake_policy(VERSION) 将产生错误。
3.31 版本变更: 弃用了对 3.10 之前版本 CMake 的兼容性。在 CMake 3.31 及以上版本中,调用未指定至少 3.10 作为其策略版本(可通过 ...<policy_max> 可选指定)的 cmake_minimum_required(VERSION) 或 cmake_policy(VERSION) 将产生弃用警告。
3.27 版本变更: 弃用了对 3.5 之前版本 CMake 的兼容性。在 CMake 3.27 及以上版本中,调用未指定至少 3.5 作为其策略版本(可通过 ...<policy_max> 可选指定)的 cmake_minimum_required(VERSION) 或 cmake_policy(VERSION) 将产生弃用警告。
3.19 版本变更: 弃用了对 2.8.12 之前版本 CMake 的兼容性。在 CMake 3.19 及以上版本中,调用未指定至少 2.8.12 作为其策略版本(可通过 ...<policy_max> 可选指定)的 cmake_minimum_required(VERSION) 或 cmake_policy(VERSION) 将产生弃用警告。
显式设置策略¶
- cmake_policy(SET CMP<NNNN> NEW|OLD)¶
告知 CMake 对给定策略使用 OLD 或 NEW 行为。依赖给定策略旧行为的项目可以通过将策略状态设置为 OLD 来静默策略警告。或者,也可以修改项目以适应新行为,并将策略状态设置为 NEW。
注意
策略的 OLD 行为根据定义已被弃用,并可能在未来版本的 CMake 中被移除。
检查策略设置¶
- cmake_policy(GET CMP<NNNN> <variable>)¶
检查给定策略是否设置为 OLD 或 NEW 行为。输出 <variable> 的值将为 OLD 或 NEW(如果已设置),否则为空。
CMake 策略栈¶
CMake 将策略设置保存在一个栈上,因此 cmake_policy 命令所做的更改仅影响栈顶。每个子目录都会自动管理策略栈上的一个新条目,以保护其父级和同级目录。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) 命令提供了一种更灵活、更安全的方式来管理策略栈。弹出操作会在离开块作用域时自动执行,因此无需在每个 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() 命令创建的命令会在它们被创建时记录策略设置,并在它们被调用时使用这些预先记录的策略。如果函数或宏实现设置了策略,这些更改会自动向上传播至调用者,直到它们到达最近的嵌套策略栈条目。