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在不同的目录了

posted @ 2020-04-20 19:04  castor_xu  阅读(250)  评论(0编辑  收藏  举报