CMake学习笔记(一)
参考链接https://cmake.org/cmake/help/latest/guide/tutorial/A%20Basic%20Starting%20Point.html
代码链接https://cmake.org/download/
对于简单的项目,只需要一个三行的CMakeLists.txt文件,如下所示:
cmake_minimum_required(VERSION 3.10)
# set the project name
project(Tutorial)
# add the executable
add_executable(Tutorial tutorial.cxx)
其中cmake的指令不区分大小写。
添加项目版本号和配置头文件
使用project()命令设置项目名称和版本号,如下所示:
cmake_minimum_required(VERSION 3.10)
# set the project name and version
project(Tutorial VERSION 1.0)
配置头文件以将版本号传递给代码:
configure_file(TutorialConfig.h.in TutorialConfig.h)
其中TutorialConfig.h.in是需要自己写的文件,TutorialConfig.h是生成的文件。
由于配置的文件将写入binary tree,因此需要将该目录添加到路径列表中以搜索包含文件。将以下行添加到CMakeLists.txt文件的末尾:
target_include_directories(Tutorial PUBLIC
"${PROJECT_BINARY_DIR}"
)
在项目目录下生成TutorialConfig.h.in文件并写入以下内容:
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
当CMakeLists.txt配置此文件时,@Tutorial_VERSION_MAJOR@和@Tutorial_VERSION_MINOR@将被替换成1和0。
将tutorial.cxx包含头文件TutorialConfig.h,并在cxx文件中打印版本号
if (argc < 2) {
// report version
std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
<< Tutorial_VERSION_MINOR << std::endl;
std::cout << "Usage: " << argv[0] << " number" << std::endl;
return 1;
}
添加C++11标准
tutorial.cxx做如下更改:
const double inputValue = std::stod(argv[1]);
在CMakeLists.txt的add_executable上方添加如下代码:
cmake_minimum_required(VERSION 3.10)
# set the project name and version
project(Tutorial VERSION 1.0)
# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
运行
mkdir build
cd build
cmake ..
make
set命令:
set(<variable> <value>... [PARENT_SCOPE]) #设置普通变量
set(<variable> <value>... CACHE <type> <docstring> [FORCE]) #设置缓存条目
set(ENV{<variable>} [<value>]) #设置环境变量
set命令可以设置普通变量、缓存条目、环境变量三种变量的值,分别对应上述三种命令格式。set的值…表示可以给变量设置0或者多个值,当设置多个值时(大于2个),多个值会通过分号连接符连接成一个真实的值赋值给变量,当设置0个值时,实际上是把变量变为未设置状态,相当于调用unset命令。
set(<variable> <value>... [PARENT_SCOPE])
将变量值variable设置为value…,变量variable的作用域为调用set命令的函数或者当前目录,如果使用了PARENT_SCOPE选项,意味着该变量的作用域会传递到上一层(也就是上一层目录或者当前函数的调用者,如果是函数则传递给函数的调用者,如果是目录则传递到上一层目录),并且在当前作用域该变量不受带PARENT_SCOPE选项的set命令的影响(如果变量之前没有定义,那么在当前作用域仍然是无定义的;如果之前有定义值,那么值和之前定义的值保持一致)。
作用域:每一个新的目录或者函数都会创建一个新的作用域,普通变量的作用域,如果不使用PARENT_SCOPE,只会从外层往内层传递。
set(<variable> <value>... CACHE <type> <docstring> [FORCE])
将缓存条目variable的值设置为value…,除非用户进行设置或者使用了选项FORCE,默认情况下缓存条目的值不会被覆盖。缓存条目可以通过CMAKE的GUI界面的add_entry按钮来增加。缓存条目的实质为可以跨层进行传递的变量,类似于全局变量。
缓存条目的type主要有以下几类:
- BOOL:布尔值ON/OFF
- FILEPATH: 文件路径
- PATH:目录路径
- STRING/STRINGS:文本行
- INTERNAL:文本行,但是只用于内部,不对外呈现。主要用于运行过程张存储变量,因此使用该type意味着使用FORCE。
缓存条目注意事项:
- 如果变量先前未定义或者使用了FORCE选项,则缓存条目会直接被赋值
- 可以在使用cmake构建的使用通过-D选项来给缓存条目赋值,这样CMakeLists.txt内的set命令只会为缓存条目添加类型。
- 如果变量类型是目录或者文件路径,通过-D选项传入的若只是相对路径,那么set会给这个相对路径钱添加当前的工作目录以变成绝对路径(如果已经是绝对路径则不会处理)。
set(ENV{<variable>} [<value>])
将环境变量设置为值value(注意没有…),接着使用$ENV{}会得到新的值。
环境变量设置的注意事项:
- 该命令设置的环境变量只在当前的cmake进程生效,既不会影响调用者的环境变量,也不会影响系统环境变量。
- 如果value值为空或者ENV{}后没有参数,则该命令会清除掉当前环境变量的值。
- value后的参数会被忽略。
unset方法说明:
一般变量:
unset(<variable> PARENT_SCOPE)
- variable:设置要清除的变量名
- PARENT_SCOPE(可选):如果set方法设置了PARENT_SCOPE,清除时,也需要带上PARENT_SCOPE
缓存变量:
unset(<variable> CACHE)
- variable:设置要清除的变量名
- 对于缓存变量清除,需要带上参数CACHE
环境变量:
unset(ENV{<variable>})
- variable:设置要清除的变量名