CMake基础指南
CMake是一个跨平台的自动化建构系统,它使用一个名为 CMakeLists.txt 的文件来描述构建过程,可以产生标准的构建文件.
在 linux 平台下使用 CMake 生成 Makefile 并编译的流程如下:
- 安装cmake,sudo apt-get install cmake
- 编写 CmakeLists.txt
- 执行命令“cmake PATH”生成 Makefile ( PATH是CMakeLists.txt 所在的目录 )
- 使用 make 命令进行编译
下面我们以例子来快速入门:
mkdir -p ~/workspace/cmake_prj
单层目录结构例子
创建目录及C代码文件
cd ~/workspace/cmake_prj
mkdir prj1 & cd prj1
gedit helloworld.c
// helloworld.c
#include <stdio.h>
int main(void){
printf("hello world!!\r\n");
return 0;
}
创建CMakeLists.txt
文件
PROJECT(helloworld) #该命令表示项目的名称是 helloworld
CMAKE_MINIMUM_REQUIRED(VERSION 2.6) #该命令限定了 CMake 的版本
AUX_SOURCE_DIRECTORY(. DIR_SRCS) #该命令会把参数 `.`当前目录 中所有的源文件名称赋值给参数 `DIR_SRCS`
ADD_EXECUTABLE(helloworld ${DIR_SRCS}) #指示变量 DIR_SRCS 中的源文件需要编译成一个名称为 main 的可执行文件
- CMakeLists.txt 的语法比较简单,由命令、注释和空格组成,其中命令是不区分大小写的。符号”#”后面的内容被认为是注释
- 命令由命令名称、小括号和参数组成,参数之间使用空格进行间隔
编译运行
cd ~/workspace/cmake_prj/prj1
cmake .
make
./helloworld
多层目录结构例子
以上的例子是单层目录结构, 但在项目中普遍是多层的目录结构. 下面我们来看看两层的目录结构:
├── prj2
│ ├── CMakeLists.txt
│ ├── hellolib.c
│ └── src
│ ├── CMakeLists.txt
│ ├── testlib.c
│ └── testlib.h
该例子中我们将会定义一个lib,并且该lib的代码在src文件夹下,prj2目录下的代码hellolib.c
会用到定义的lib.
先编写简单lib代码
cd ~/workspace/cmake_prj & mkdir prj2 & cd prj2 & mkdir src & cd src
gedit testlib.h
gedit testlib.c
// testlib.h
#include <stdio.h>
int add(int a,int b);
// testlib.c
#include "testlib.h"
int add(int a,int b){
return (a+b);
}
在lib目录下创建CMakeList.txt文件
AUX_SOURCE_DIRECTORY(. DIR_LIB_SRCS)
ADD_LIBRARY(testlib ${DIR_LIB_SRCS}) #将src目录中的源文件编译为共享库testlib
在prj2
目录下创建主函数代码
cd ~/workspace/cmake_prj/prj2
gedit hellolib.c
// hellolib.c
#include "src/testlib.h"
int main(void){
int a=11,b=12;
int sum = add(a,b);
printf("%d + %d = %d\r\n",a,b,sum);
}
再创建整个工程的CMakeLists.txt
PROJECT(hellolib)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
ADD_SUBDIRECTORY(src) # 指明本项目包含一个子目录 src
AUX_SOURCE_DIRECTORY(. DIR_SRCS)
ADD_EXECUTABLE(hellolib ${DIR_SRCS})
TARGET_LINK_LIBRARIES(hellolib testlib) #指明可执行文件 hellolib 需要连接一个名为testlib的链接库
编译执行
cd ~/workspace/cmake_prj/prj2
make .
make
./hellolib
外部构建例子
以上两个例子其实都为内部构建, 你会发现构建后会生成很多临时文件,与CMakeLists.txt
或者源代码混杂在一起.
这对于版本管理比如git不是很友好,需要重新编辑.gitignore
文件,比较麻烦.
此时,若使用外部构建将会方便很多,我们以上面的例子2为基础来演示.
拷贝prj2工程到prj3, 并删除多余的文件,若有的话.
cd ~/worksapce/cmake_prj
cp -R prj2 prj3
在prj3下创建build目录,并在build目录下执行cmake
cd ~/worksapce/cmake_prj/prj3
mkdir build & cd build
cmake ../ ## cmake的path是父目录
此时,在build目录下生成了编译需要的Makefile以及其它的临时文件.
这样对于原有的工程没有任何影响,所有动作全部发生在编译目录build内.
编译执行
cd ~/worksapce/cmake_prj/prj3/build
make
./hellolib