【CMake 项目】CMake 版本兼容:最低版本需求和策略

当我们使用 CMake 工具编译项目的 CMakeLists.txt 存在两个问题。
第一个问题是 CMake 工具版本太旧
第二个问题是 CMake 工具版本太新

CMake 工具版本太旧的话,可能 CMakeLists.txt 使用了新的语法,就会不兼容
CMake 工具版本太新的话,也会出现不兼容问题,因为 CMake 新版本更新时 不一定向后兼容CMake 老版本的一些功能可能删除更改

如果我们使用了 CMake 新的语法

如果我们使用了 CMake 新的语法,那么需要通过 cmake_minimum_required() 命令限制 CMake 最低版本需求

如果 CMake 运行的版本 不在 <min>...<max> 版本 之间,会报错。

cmake_minimum_required() 命令,语法如下:

cmake_minimum_required(VERSION <min>[...<max>] [FATAL_ERROR])

<min><max> 表示 CMake 版本区间,每个 CMake 版本major.minor[.patch[.tweak]] 的组成。

FATAL_ERROR 选项,在 CMake 2.6 及更高版本忽略。如果使用 CMake 2.4 及耕地版本,失败时,显示错误,而不仅仅是警告。

使用 cmake_minimum_required() 命令,会隐式调用 cmake_policy(VERSION) 命令,指定版本引入的所有策略都将设置为 NEW 行为。

cmake_policy() 命令有多种形式,关于设置全局策略,语法如下

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

例如,我们由于使用了新版本的语法,CMake 版本 最低为 3.0

cmake_minimum_required(VERSION 3.0)

# 相当于调用了 
cmake_policy(VERSION 3.0)

例如,在上面例子上,加上最高版本为 3.7

cmake_minimum_required(VERSION 3.0...3.7)

# 相当于调用了 
cmake_policy(VERSION 3.0...3.7)

如果 CMake 运行的版本<min>...<max> 版本更早版本中,引入的所有策略都将设置为 NEW 行为。高于设置的版本,引入所有的策略都将取消设置。

只有通过 cmake_policy() 显示设置策略,才会有用。如果需要运行 的 CMake 版本 高于 3.0,但是引入的策略为 CMake 版本3.03.5 之间。

cmake_minimum_required(VERSION 3.0)
cmake_policy(VERSION 3.0...3.5)

策略中 NEWOLD 的区别

例如,我们在 CMake 3.0 版本中,引入策略 CMP0048。表示在 CMake 3.0 版本中,引入 project() 命令使用 VERSION 设定版本。

默认情况下,cmake-3.19.2 会启用策略 CMP0048。如果不想使用该策略,通过 cmake_policy 命令设置为 OLD。一般设置该策略为 OLD,如果在 project() 命令使用 VERSION 会报错。

if(POLICY CMP0048)
  cmake_policy(SET CMP0048 OLD)
endif()

通过 cmake_policy 命令设置为 NEW,使用该策略。

if(POLICY CMP0048)
  cmake_policy(SET CMP0048 NEW)
endif()

上述是通过 显示设置策略,通过给定策略使用 OLDNEW 行为,语法如下。

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

更多策略参考 cmake-policies(7)

避免策略兼容性警告

我们虽然指定了 CMake 最低运行版本,但是源文件使用了高于 CMake 版本 的语法,但是我们不想为了使用了 新的语法,而更改 cmake_minimum_required() 命令,那么怎么做?

对于一些不重要的策略,可以使用一种兼容的手段。如果运行的 CMake 版本 足够,支持该策略,那么设置为 NEW 行为,因为使用 cmake_minimum_required() 命令通过隐式设置的最新策略为 OLD 行为;如果运行的 CMake 版本 不足够,不支持该策略,那么什么都不做。

cmake_minimum_required(VERSION 2.6)
if(POLICY CMP0048)
  cmake_policy(SET CMP0048NEW)
endif()

如果 CMake 运行版本虽然高于 3.0,但是因为使用 cmake_minimum_required(VERSION 2.6) 指定策略版本为 2.6CMP0048 策略是 CMake 3.0 引入的,用兼容性语法,不会发出兼容性警告。

检查策略设置

cmake_policy(GET) 检查策略是否设置为 OLDNEW 行为,如果未设置策略,返回 空。

cmake_policy() 命令检查策略设置,语法如下:

cmake_policy(GET CMP<NNNN> <variable>)

CMake 策略堆栈

CMake策略设置保存在一个栈结构中,当进入一个项目子目录时,就会在策略栈入栈新的一层元素,离开子目录时就会出栈这层元素。因此在一个项目子目录设置策略不会影响父目录以及同层路径,但会影响子目录

这在一个项目包含了多个分别维护的子目录但在一起编译时非常有用,它可以让不同的子目录使用不同的策略版本

用户可以使用 cmake_policy 命令入栈出栈自己的临时策略层,只要入栈出栈成对出现的,这对于临时对一小段代码改变策略设置时比较有用。

cmake_policy (PUSH)
#change cmake policy
#do something
cmake_policy (POP)
  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值