[cmake]cmake命令之cmake_policy

本文详细介绍了CMake中的策略机制,用于处理版本间的后向兼容性问题。通过cmake_policy设置策略的OLD和NEW值,以及cmake_minimum_required的自动策略设置,展示了如何确保构建工程在不同CMake版本间的兼容性。
摘要由CSDN通过智能技术生成

CMake中的策略机制是用来保证多个版本之间的后向兼容性,也就是当新版本的CMake在某些特性上有变更时,如何对已有构建工程保持兼容的一种手段。当引入新的策略时,新的CMake版本会对后向兼容行为发出告警,可以通过显式的在策略中指定OLD(保持后向兼容行为)来禁止告警,或者在策略中指定NEW(不后向兼容)也会禁止告警,不过NEW会放弃后向兼容。

策略的定义形式

通过CMP<NNNN>形式来唯一定义一个策略,例如CMake3.23版本,定义的策略有130个,从CMP0000CMP0129

如何在CMake中设置策略

每个策略都有OLD(保持后向兼容性)和NEW(不保持后向兼容性)两个值,可以通过如下两种方式来设置:

  • 通过cmake_policy命令针对单个策略进行设置:cmake_policy(SET CMP<NNN> NEW)cmake_policy(SET CMP<NNN> OLD)
  • 通过cmake_policy命令针对指定的版本区间进行设置:cmake_policy(VERSION <min>[...<max>] NEW)cmake_policy(VERSION <min>[...<max>] NEW),其中版本区间的<max>是可选的;
  • 在命令行中通过CMAKE_POLICY_DEFAULT_CMP<NNN>来将策略的行为设置为OLDNEWcmake -DCMAKE_POLICY_DEFAULT_CMP<NNNN>=NEW .cmake -DCMAKE_POLICY_DEFAULT_CMP<NNNN>=OLD .

注意:策略机制不是一个可靠的功能开关,也不建议将其设置为OLD,在将来的版本中可能会使用错误来替代当前的告警提示。

一些示例说明

本文所使用的相关软件版本:

软件名称软件版本
Linux操作系统Ubuntu 22.04 LTS
cmake3.22.1
  • cmake_minimum_required命令除了在CMake版本过低时产生一条错误之外,它还会隐式地调用make_policy,将该命令中指定的CMake版本及之前版本引入的策略都设置为NEW。举个例子:CMP0072这个策略是在3.11版本中引入,因此如果cmake_minimum_required中的版本大于等于3.11时,CMP0072会被默认置为NEW,当cmake_minimum_required中的版本小于3.11时,CMP0072则是未定义的。

    1)对于策略CMP0072cmake_minimum_required指定版本小于3.11时,本文例子中为3.10,该策略的值是未定义(空)

 CMAKE_MINIMUM_REQUIRED(VERSION 3.10)
 PROJECT(policy_test)
 CMAKE_POLICY(GET CMP0072 var)
 MESSAGE("CMP0072 behavior is: ${var}")

> 输出结果:
> `CMP0072 behavior is:`

2)对于策略CMP0072cmake_minimum_required指定版本大于等于3.11时,本文例子中为3.20,该策略的值是NEW

   CMAKE_MINIMUM_REQUIRED(VERSION 3.20)
   PROJECT(policy_test)
   CMAKE_POLICY(GET CMP0072 var)
   MESSAGE("CMP0072 behavior is: ${var}")

> 输出结果:
> `CMP0072 behavior is: NEW`
  • 可以通过判断策略是否存在的方式,使用if命令(if命令可以参考这里)判断,并通过cmake_policy来显示的将策略设置为NEW

    CMAKE_MINIMUM_REQUIRED(VERSION 3.10)
    PROJECT(policy_test)
    CMAKE_POLICY(GET CMP0072 var)
    MESSAGE("CMP0072 behavior is: ${var}")
    
    
    if(POLICY CMP0072)
     CMAKE_POLICY(SET CMP0072 NEW)
    endif()
    CMAKE_POLICY(GET CMP0072 var)
    MESSAGE("Finally CMP0072 behavior is: ${var}")

> 输出结果:
> `CMP0072 behavior is: Finally CMP0072 behavior is: NEW`
  • CMP0000:必须指定CMake的最小要求版本,在2.6版本中引入。默认情况下必须在CMakeLists.txt的第一行调用cmake_minimum_required命令指定要求的最小CMake版本,如果没有指定,则会报错。

    1)如果未调用cmake_minimum_required,默认情况下会报错

    # CMakeLists.txt文件内容
    PROJECT(policy_test)

> 输出结果:
> CMake Error in CMakeLists.txt:  No cmake_minimum_required command is present. A line of code such as
> `cmake_minimum_required(VERSION 3.22)`
> should be added at the top of the file. The version specified may be lower  if you wish to support older CMake versions for this project. For more  information run "cmake --help-policy CMP0000".

2)我们可以使用cmake -DCMAKE_POLICY_DEFAULT_CMP0000=OLD .来禁止这个策略,不需要指定最小版本(CMakeLists.txt的第一行不调用cmake_minimum_required命令),但是CMake仍然会产生一条告警

    # CMakeLists.txt文件内容
    PROJECT(policy_test)
    CMAKE_POLICY(GET CMP0072 var)
    MESSAGE("CMP0072 behavior is: ${var}")
    
    # 命令行中调用
    cmake -DCMAKE_POLICY_DEFAULT_CMP0000=OLD .

> 输出结果:
> CMP0072 behavior is:
> CMake Warning:  Manually-specified variables were not used by the project:
> `CMAKE_POLICY_DEFAULT_CMP000`

需要注意的是,某些场景下设置策略是受约束的,设置的策略行为不会传递到上层范围。例如,通过include()或者find_package()命令调用包含的文件中,如果有使用cmake_policy,该策略是不会影响到命令的调用者。当然,这两个命令都可以通过NO_POLICY_SCOPE选项来控制策略的传递范围。


附录:参考文档

  1. https://cmake.org/cmake/help/latest/command/cmake_policy.html

  2. https://cmake.org/cmake/help/latest/manual/cmake-policies.7.html#manual:cmake-policies(7)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

被代码搞废的挖掘机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值