cmake实践(1)--最基本的helloworld
最近找了一个《cmake practice》的电子书,觉得写得比较清晰易懂,适合我这种noob,本随笔主要内容基于该电子书,因此会出现“过渡引用”的问题,主要目的是作为自己的学习笔记。
另外英语比较好的可以直接去看Github,地址是https://github.com/Akagi201/learning-cmake
个人觉得,写cmake本身的技术要求,同掌握一门脚本语言相当,某种程度上可能难度还高一些。
废话少说,开始学习。
初识和安装就算了,这都解决不了那就没法玩了。
直接从基本编译文件开始。
先在主目录下创建一个测试的目录,例如我的主目录是/home/castor/,那就搞一个mycmake的文件夹,再搞一个t1的文件夹。
~$cd ~$mkdir -p mycmake/t1
接下来就是在这个文件夹下面创建两个文件了:
~$ cd mycmake/t1/ castor@xdvm:~/mycmake/t1$ touch main.c castor@xdvm:~/mycmake/t1$ touch CMakeLists.txt
然后main.c中是经典的helloworld代码,或者其他,这里直接复制文档中的代码:
#include <stdio.h> int main() { printf("Hello World from t1 Main!\n"); return 0; }
当然这个不是重点,看看CMakeLists.txt中怎么写:
PROJECT (HELLO) SET(SRC_LIST main.c) MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR}) MESSAGE(STATUS "This is SOURCE dir " ${HELLO_SOURCE_DIR}) ADD_EXECUTABLE(hello ${SRC_LIST})
原文档第六页的代码有bug,最后一行SRC_LIST没有被$和花括号包起来。
构建和运行很简单:
~/mycmake/t1$ cmake . ~/mycmake/t1$ make
执行后大概是这样的:
然后就可以通过./hello运行程序了。
解释一下:cmake .(注意后面的小句点),这个命令生成了很多文件,目前需要知道的是,以及重点是,生成了Makefile文件。然后make就是按这个Makefile生成可执行文件。
最重点的还是CMakeLists文件了。
PROJECT定义了工程的名字
cmake 系统也帮助我们预定义了 PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR变量,他们的值分别跟 HELLO_BINARY_DIR 与 HELLO_SOURCE_DIR(这两个是隐式变量) 一致,如果项目名字变化,PROJECT_BINARY_DIR 和PROJECT_SOURCE_DIR能够自适应。
SET 指令的语法是:
SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
现阶段,你只需要了解 SET 指令可以用来显式的定义变量即可。
比如我们用到的是 SET(SRC_LIST main.c),如果有多个源文件,也可以定义成:
SET(SRC_LIST main.c t1.c t2.c)。
MESSAGE 指令的语法是:
MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display"...)
这个指令用于向终端输出用户定义的信息,包含了三种类型:
SEND_ERROR,产生错误,生成过程被跳过。
SATUS,输出前缀为--的信息,图中可以看到。
FATAL_ERROR,立即终止所有 cmake 过程。
如果不加这三种也是可以的,那就是一个普通的信息,有点类似echo了。
ADD_EXECUTABLE(hello ${SRC_LIST})
定义了这个工程会生成一个文件名为 hello 的可执行文件 ,这个SRC_LIST就是前面定义的一个变量。
虽然这里看起来有点多此一举,但是如果多次出现的多个文件的话,就会发现这种方式很方便。
cmake中使用了${}来引用变量,这是 cmake 的变量引用方式,但是,有一些例外,比如在 IF 控制语句,变量是直接使用变量名引用,而不需要${},这个要小心。
基本语法规则
1. 变量使用${}方式取值,但是在 IF 控制语句中是直接使用变量名
2. 指令(参数 1 参数 2...) 参数使用括弧括起,参数之间使用空格或分号分开
3. 指令是大小写无关的,参数和变量是大小写相关的。 推荐全部使用大写指令
4. 后面学习到了再加上
使用make clean 命令清除构建(感觉用处不大)
刚才进行的是内部构建(in-source build),而 cmake 强烈推荐的是外部构建(out-of-source build)
外部编译的过程如下:
1,首先,请清除 t1 目录中除 main.c CmakeLists.txt 之外的所有中间文件,最关键的是 CMakeCache.txt。
2,在 t1 目录中建立 build 目录,当然你也可以在任何地方建立 build 目录,不一定必须在工程目录中。
3,进入 build 目录,运行 cmake ..(注意,..代表父目录,因为父目录存在我们需要的CMakeLists.txt,如果你在其他地方建立了 build 目录,需要运行 cmake <工程的全路径>),查看一下 build 目录,就会发现了生成了编译需要的 Makefile 以及其他的中间
文件.
4,运行 make 构建工程,就会在当前目录(build 目录)中获得目标文件 hello。
上述过程就是所谓的 out-of-source 外部编译,一个最大的好处是,对于原有的工程没有任何影响,所有动作全部发生在编译目录。
使用外部构建以后,可以看到:
-- This is BINARY dir /home/castor/mycmake/t1/build
-- This is SOURCE dir /home/castor/mycmake/t1
binary和source在不同的目录了