对CMake笔记 1-初学cmake进行解析;
之前写的CMakeLists.txt进行逐条学习;
PROJECT(HELLO)
SET(SRC_LIST "main.cpp")
MESSAGE(STATUS "This is BINARY dir" ${HELLO_BINARY_DIR})
MESSAGE(STATUS "This is SOURCE dir" ${HELLO_SOURCE_DIR})
ADD_EXECUTABLE(hello ${SRC_LIST})
注意:CMakeLists.txt文件是cmake的构建定义文件,文件名是区分大小写的,所以必须是CMakeLists.txt,这样才能cmake成功;如果一个项目中由多个目录构成,就需要确保每个管理的目录都存在一个CMakeLists.txt。
PROJECT
PROJECT(projectname [CXX] [C] [Java])
使用PROJECT定义工程名称,并可指定工程支持的语言,默认支持所有语言;
PROJECT隐式定义了两个cmake变量:
<projectname>_BINARY_DIR以及<projectname>_SOURCE_DIR,在当前这个例子中
<projectname>_BINARY_DIR:HELLO_BINARY_DIR;
<projectname>_SOURCE_DIR:HELLO_SOURCE_DIR;
MESSAGE指令中就是使用的这两个变量:${HELLO_BINARY_DIR}和${HELLO_SOURCE_DIR};
当前这两个变量的路径是CMakeLists.txt所在的文件路径:/backup/cmake/t1
与此同时,cmake也自动预定义了两个变量:PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR;
PROJECT_BINARY_DIR对应<projectname>_BINARY_DIR;
PROJECT_SOURCE_DIR对应<projectname>_SOURCE_DIR;
注意:在以后使用中,直接使用PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR,这样以后修改工程名称,也不会影响这两个变量的内容的使用;
注意:变量的使用可以使用${}来引用变量,但是也有例外,比如在IF控制语句,变量是直接使用变量名引用,而不需要${}。
SET
SET(VAR [VALUE\] [CACHE TYPE DOCSTRING [FORCE]])
SET指令可以用来显示的定义变量;
当前指令为:SET(SRC_LIST “main.cpp”)
如果有多个源文件,可以使用:SET(SRC_LIST “main.cpp t1.c”)或者SET(SRC_LIST main.cpp t1.c)
ADD_EXECUTABLE
ADD_EXECUTABLE(hello ${SRC_LIST})
这条指令指定了这个工程会生成一个文件名为hello的可执行文件,相关的源文件是SRC_LIST中定义的源文件列表;
也可以直接写成ADD_EXECUTABLE(hello main.c)
MESSAGE
MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display"...)
MESSAGE用于向终端输出用户定义的信息;
信息分为三种类型:
类型 | 功能 |
---|---|
SEND_ERROR | 产生错误,生成过程被跳过 |
STATUS | 输出前缀为—的信息 |
FATAL_ERROR | 立即终止所有 cmake 过程 |
基本语法
cmake要求使用用”cmake 语言和语法”去构建;
cmake最简单的语法规则:
1.变量使用${}方式取值,但是在 IF 控制语句中是直接使用变量名;
2.指令(参数 1 参数 2…);
注意:指令使用的参数使用括号包起来,参数之间使用空格或分号分开;
例如,有多个源文件在项目中,两种表示方式:
ADD_EXECUTABLE(hello main.c func.c)
ADD_EXECUTABLE(hello main.c;func.c)
3.指令是大小写无关的,参数和变量是大小写相关的。但,推荐全部使用大写指令。
注意:在编写CMakeLists.txt时要形成统一的风格;
对构建后的结构进行清理,使用命令make clean,下图是使用make clean前后的对比;
啥是内部构建与外部构建
内部构建:生成的临时文件放在源码同级目录下,删除中间临时文件比较麻烦;
外部构建:创建了一个文件夹用于存储生成的编译文件,可以更好删除编译生成的文件;
cmake强烈推荐使用外部构建;
外部构建的过程:
1.代码文件夹内只有代码和CMakeLists.txt;
2.在任意地方建立build目录;
3.进入build目录,运行cmake …(注意,…代表父目录,因为父目录存在我们需要的
CMakeLists.txt,如果你在其他地方建立了 build 目录,需要运行 cmake <工程的全 路径>),查看一下 build 目录,就会发现了生成了编译需要的 Makefile 以及其他的中间文件。
4.在build目录内,运行make构建工程,就会在build目录中获得目标文件;
外部构建的好处:对于原有的工程没 有任何影响,所有动作全部发生在编译目录。
注意:外部构建中,<projectname>_SOURCE_DIR 仍然指代工程路径;而 <projectname>_BINARY_DIR 则指代编译路径,即build所在位置;
用之前的例子,试运行外部构建;
可以看到BINARY的路径有改变,指向了build所在文件夹;