CMake 从入门到崩溃3 - 基础语法之作用域
CMake 从入门到崩溃3 - 基础语法之作用域
我们介绍了 CMake 变量的使用,在这篇里我们会讲解 CMake 是怎样做名字查找的,也就是 CMake 中的变量作用域,由于 CMake 的作用域和其他编程语言区别很大,因此理解 CMake 作用域机制对正确的写出 CMake 脚本帮助很大
CMake 本质上是一个基于目录的作用域,设置一个变量,将为该文件和它的全部子目录设置该变量
CMake 中的名字查找沿作用域树向上做查找,因此你在子目录中修改了变量的值,只会影响到子目录及更深的目录,并不会对父目录产生任何影响
- CMake 如果在当前作用域找不到该变量,就会到 Cache 中去找
?? 条件语句和循环语句都不会引入新的作用域,这点和大多数编程语言都不同
set 命令提供了两个作用域相关的选项:
PARENT_SCOPE
将在父作用域而不是当前作用域设置该变量CACHE
会将该变量写到 CMakeCache 中,set 的结果在所有作用域中都有效
子 CMake 脚本的作用域:
add_subdirectory
会引入新的作用域include
在原有作用域中执行- 执行
set()
和unset()
影响的是调用者的作用域
- 执行
除了基于目录的作用域外,CMake 函数还有自己的作用域,这意味着在函数中设置变量不会渗透到父作用域中,但对宏来说不是这样,因此我们更倾向于使用函数而不是宏
add_subdirectory
add_subdirectory(source_dir [binary_dir])
add_subdirectory
添加一个用于构建的子目录
source_dir
source_dir
通常是相对于当前目录的相对路径,但也可以指定它为绝对路径
CMake 将首先去执行 source_dir
目录下的 CMakeLists.txt
,结束后再转回当前命令的下一行继续执行
调用 add_subdirectory
将导致在源码树中建立一个新结点,可以通过 CMAKE_CURRENT_SOURCE_DIR
获取到当前处理结点的完整路径
binary_dir
选项 binary_dir
用于指定子目录的输出应该放置在哪里,通常是相对于当前输出目录的相对路径,但也可以指定它为绝对路径
- 典型的用法是,不去指定
binary_dir
,未展开为绝对路径的source_dir
的值将被用作binary_dir
- 调用
add_subdirectory
后,构建树中往往也会增加一个新结点,如果我们从来不指定binary_dir
选项,源码树和构建树的结构应该是相同的 - 这里说的输出包含 CMake 生成的构建系统文件和各种临时文件,如果仅仅想要改变目标生成的位置,比如二进制或库文件,应该通过
set_target_properties
命令改变对应目标的*_OUTPUT_DIRECTORY
属性