从事linux的开发工作,不可避免的需要进行编译构建的工作,相比在Windows上的使用VS直接开发c++程序,在Linux上开发c++程序,需要直接编辑Makefile,不仅需要熟悉Makefile的语法,还需要知道依赖和推导规则,比较麻烦。而CMake是开源、跨平台的构建工具,可以让我们通过编写简单的配置文件去生成本地的Makefile,这个配置文件是独立于运行平台和编译器的,这样就不用亲自去编写Makefile了,而且配置文件可以直接拿到其它平台上使用,无需修改,非常方便。学会该工具的使用,无疑是性价比非常高的。
最简单的一个例子
首先让我们从最简单的代码入手,先来体验下cmake是如何操作的。编写main.c,如下:
#include <stdio.h>
int main(void)
{
printf("Hello World\n");
return 0;
}
然后在main.c相同目录下编写CMakeLists.txt,内容如下:
#指定使用该CMakeList.txt文件需要的cmake最低版本
cmake_minimum_required (VERSION 3.5)
#指定项目信息
project (demo)
#指定生成目标
add_executable(main main.cpp)
最后执行下面脚本,进行创建build目录、生成Makefile、编译连接的操作。
mkdir build
cd build
cmake ../
make
这样,我们便可以看到我们需要的elf文件main也成功生成了,然后运行main
这里解释一下为什么在build目录下运行cmake?如果不这样做,cmake运行时生成的附带文件就会跟源码文件混在一起,这样会对程序的目录结构造成污染,而在build目录下运行cmake,生成的附带文件就只会待在build目录下,如果我们不想要这些文件了就可以直接清空build目录,非常方便。
同一目录下多个源文件
接下来进入稍微复杂的例子:在同一个目录下有多个源文件。
在之前的目录下添加2个文件,testFunc.cpp和testFunc.h。添加完后整体文件结构如下,
├── testFunc.cpp
├── testFunc.h
├── CMakeLists.txt
└── main.cpp
那现在怎么把增加的文件编译进去呢?我们只需要简单修改一下CMakeLists.txt文件即可
add_executable(main main.cpp testFunc.cpp)
依此类推,如果在同一目录下有多个源文件,那么只要在add_executable里把所有源文件都添加进去就可以了。但是如果有一百个源文件,再这样做就有点坑了,无法体现CMake的优越性,CMake提供了一个命令可以把指定目录下所有的源文件存储在一个变量中,这个命令就是 aux_source_directory(dir var)。
第一个参数dir是指定目录,第二个参数var是用于存放源文件列表的变量。
我们在main.cpp所在目录下再添加2个文件,testFunc1.cpp和testFunc1.h。添加完后整体文件结构如下,
├── testFunc.cpp
├── testFunc.h
├── CMakeLists.txt
├── main.cpp
├── testFunc1.cpp
└── testFunc1.h
修改CMakeLists.txt,
cmake_minimum_required (VERSION 3.5)
project (demo)
### 使用aux_source_directory把当前目录下的源文件存列表存放到变量SRC_LIST里
aux_source_directory(. SRC_LIST)
### 在add_executable里调用SRC_LIST
add_executable(main ${SRC_LIST})
aux_source_directory()也存在弊端,它会把指定目录下的所有源文件都加进来,可能会加入一些我们不需要的文件,此时我们可以使用set命令去新建变量来存放需要的源文件,如下,
cmake_minimum_required (VERSION 3.5)
project (demo)
set( SRC_LIST
./main.cpp
./testFunc1.cpp
./testFunc.cpp)
add_executable(main ${SRC_LIST})
不同目录下多个源文件
一般来说,当程序文件比较多时,我们会进行分类管理,把代码根据功能放在不同的目录下,这样方便查找。那么这种情况下如何编写CMakeLists.txt呢?
我们把之前的源文件整理一下(新建2个目录t