1. cmake介绍
在早期和当今的Linux工程管理中,make工程管理器占据了半壁江山,但make的配置文件Makefile的语法晦涩难懂,接触过的人都清楚,Makefile写起来非常困难。解决这个问题的办法无法有两个:
- 使用 automake 工具生成configure脚本,让其自动生成Makefile。
- 使用 cmake 工具直接生成Makefile。
第一种方法在上一章中已详细介绍,此处着重讲解第二种方式。
1.1 cmake是什么
cmake 是一款跨平台的免费开源软件工具,用于使用与编译器无关的方法来管理软件的构建过程。比如,在 Android Studio 上进行 NDK 开发默认就是使用
cmake 管理 C/C++ 代码,在 Linux 环境下有大量项目都使用
cmake 来管理,因此最好对
cmake 有一定的了解。
cmake

cmake最重要的作用就是协助我们自动生成项目所需要的Makefile,以便于工程管理器make可以指导编译器的工作,他们的关系大概如下:
cmakemakegcc
CMakeLists.txtMakefile可执行程序源代码
- 开发者编写CMakeLists.txt,指导cmake自动生成Makefile
- 自动生成的Makefile,指导make和gcc,将源代码编译成可执行程序
这样一来,我们就摆脱了晦涩难写的Makeifle,转而编写简单可爱的
CMakeLists.txt ,利用cmake即可管理整个项目。
2. 安装cmake
2.1 在 ubuntu 中安装 cmake
ubuntu安装
cmake 只需一条指令:
gec@ubuntu:~$ sudo apt install cmake
可以通过以下指令来查看当前已安装的
cmake 的版本,若需要升级版本,可直接使用
apt 指令来升级:
# 查看cmake版本 gec@ubuntu:~$ cmake --version
# 升级cmake gec@ubuntu:~$ sudo apt upgrade cmake
2.2 在 windows 中安装 cmake
可以在
cmake 的
官网 下载其源码,或挑选符合用户操作系统的二进制安装包即可。
3. 简单示例
3.1 入门操作
假设有一C语言源程序
main.c ,其内容如下:
#include <stdio.h>
int main(int argc, char const *argv[])
{
printf("一起学习cmake\n");
return 0;
}
现使用
cmake 来管理该项目的构建工作,在
main.c 同一目录下,编写一个
CMakeLists.txt:
gec@ubuntu:~/cmake$ tree
.
├── CMakeLists.txt
└── main.c
gec@ubuntu:~/cmake$
文件
CMakeLists.txt 是 cmake 的配置文件,用来告诉 cmake 如何生成最终的
Makefile。此处的
CMakeLists.txt 非常简单,仅包含一句话:
# CMakeLists.txt add_executable(main main.c)
注意:
- 配置文件的名称 CMakeLists.txt 是固定的,不可改成别的名字
- 配置文件的名称 CMakeList.txt 不区分大小写,但一般的写法如此所示。
- add_executable 用来指明最终要生成一个可执行文件的名称,及其所依赖的源文件列表。
在源码目录中,直接执行命令 “
cmake .”(其中
. 表示
CMakeLists.txt 所在的位置在当前目录) 来读取
CMakeLists.txt 并生成
Makefile:

此时会发现,目录中自动生成了Makefile了:

有了Makefile,就可以直接make编译项目程序了:

此时,程序main已经编译完毕。
3.2 源码隔离
一般而言,为了项目工程观感更干净、利落,我们不希望源码跟编译工具文档像上面的例子那样混在一起,因此对于cmake而言,通常的操作是:在源码中创建一个专门用于存储编译输出文件的存储区域,不妨命名为
build/ ,使自动生成的文件与开发者编写的源码隔离:
# 创建一个构建目录,专门用来存放构建过程中产生的非源码文件
gec@ubuntu:~/cmake$ mkdir build/
# 进入该构建目录
gec@ubuntu:~/cmake$ cd build
gec@ubuntu:~/cmake/build$
# 在构建目录中执行 `cmake`
gec@ubuntu:~/cmake/build$ cmake ..
这样,项目构建过程中产生的所有非源码文件就都被保存在
build 目录下了:
.
├── build/
│ ├── CMakeCache.txt
│ ├── CMakeFiles/
│ ├── cmake_install.cmake
│ └── Makefile
├── main.c
└── CMakeLists.txt
有了
Makefile 就可以直接编译了:
# 编译
gec@ubuntu:~/cmake/build$ make
Scanning dependencies of target main
[ 50%] Building C object CMakeFiles/main.dir/main.o
[100%] Linking C executable main
[100%] Built target main
# 查看编译结果
gec@ubuntu:~/cmake/build$ ls -lp
total 39
-rwxrwxrwx 1 root root 12281 May 31 20:30 CMakeCache.txt
drwxrwxrwx 1 root root 4096 May 31 20:30 CMakeFiles/
-rwxrwxrwx 1 root root 1441 May 31 20:30 cmake_install.cmake
-rwxrwxrwx 1 root root 16736 May 31 20:30 main
-rwxrwxrwx 1 root root 4868 May 31 20:30 Makefile
# 执行程序
gec@ubuntu:~/cmake/build$ ./main
一起学习cmake