美文网首页
Cmake命令之cmake_policy

Cmake命令之cmake_policy

作者: Domibaba | 来源:发表于2023-08-24 12:31 被阅读0次

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
cmake 3.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)

相关文章

网友评论

      本文标题:Cmake命令之cmake_policy

      本文链接:https://www.haomeiwen.com/subject/wqqpmdtx.html