背景
目前很多大型框架都是使用cmake去构建,如果看不懂cmake, 在实际修改框架,添加新的模块时候就会受制于人,为此需要了解cmake的相关基础支持,避免被某些装逼大佬卡脖子,同时也进一步提高自己的业务水平。
变量
cmake里面的变量主要有两种方式:option 和 set 两种方式,简单如下:
set(var "hello") //set(变量名 值)
option(use_option "opiton" ON) //option(变量名 “信息说明” 值)
option
其实option可以等效于:
set(use_option ON CACHE BOOL "option") //set(变量 值 CACHE 类型 “信息说明”)
为什么说可以等效于set,因为可以通过生成的CMakeCache.txt查找到这个值。当在写CMakeLists.txt的时候没有给一个ON的值的时候(为空,为OFF, 或者其他乱七八糟的字符串的时候),我们查看CMakeCache.txt的时候会发现use_option都是被设置为OFF。
set
- 变量类似于C++语言,有先后的顺序,只有先声明或者定义,后面的代码才可见。
- 变量作用域概念,为了方便简单参考下面的文件布局,当在主目录的CMakeLists.txt中定义一个变量时,在first中CMakeLists.txt会把主目录的的变量
拷贝
到子目录,类似C++中的函数传值概念,所以在子目录中怎么修改都不会改变其他子目录的值,以及主目录的值。
- cache 概念,cache可以理解为全局变量,官网解释说当作一个config, 会存在CMakeCache.txt中,在定义的时候会给一个默认值。下面是一个demo, 首先在first文件中如下设置:
set(first "first")
set(cache "first set cache" CACHE STRING "test cache")
message(STATUS "${first}")
在second中
set(second "second")
message(STATUS "${second}")
message(STATUS "second show cache = ${cache}")
set(cache "second change cache" CACHE STRING "SECOND TEST CACHE")
message(STATUS "after chage in second = ${cache}")
在主目录中
1 cmake_minimum_required(VERSION 3.12)
2 project(hello)
3
4 set(hello "hello")
5 message(STATUS "${hello}")
6 if(DEFINED cache)
7 message(STATUS "${cache}")
8 else()
9 message(STATUS "no cache")
10 endif()
11
12 add_subdirectory(first)
13 add_subdirectory(second)
14
15 message(STATUS "main subdirectory = ${cache}")
结果:cmake …
好好体会上面的代码。
关于set问题
- 为什么在second中set(cache “second change cache” CACHE STRING “SECOND TEST CACHE”)没有生效??
- 如果改成set(cache “second change cache”)会有什么效果?
- cmake … -Dcache=“change cache” 执行呢?
回答
问题一:当CMakeCache.txt中已经有了变量名字,再次定义的会会被直接忽略。
问题二:当修改后,在second文件中会出现一个局部变量cache, cmake的逻辑是优先读取局部cache的值。效果如下:
问题三:可以理解在main目录下起始位置定义一个局部变量cache,后面子目录也会拷贝到自己的作用域,所以结果可想而知: