由于cmake内容较多,篇幅较长,为了不让人疲倦,分成了多篇博客,全部博客链接如下


这是博客cmake简洁教程的第三篇,主要介绍如何更"正规"地使用cmake

一般来说,正规的工程会符合以下几条规则

1. 把所有的头文件放在子目录include中

2. 把所有的源文件放在子目录src中

3. 把要编译的目标文件(可执行程序,库文件)放在子目录bin中

4. 把编译的临时文件放在子目录build中,这样就不会都产生在工程根目录下碍眼了

接着上篇博客的例子,我们再次改造,如下图所示(按照上面的规则,把文件重新挪了下位置)

cmake简洁教程 - 第三篇_子目录

 这种情况下CMakeLists.txt该怎么写才能满足上面的规则呢?其实也很简单

第一步:先在工程根目录建一个CMakeLists.txt文件,内容如下

cmake_minimum_required (VERSION 3.5)
project (demo)
add_subdirectory (src)

第3行:新命令,意思是添加了一个cmake的子目录,且该目录下有CMakeLists.txt文件,请构建之

第二步:再在子目录src中建一个CMakeLists.txt文件,内容如下

aux_source_directory (. SRC_LIST)
include_directories (../include)
add_executable (main ${SRC_LIST})
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

我们详细解释下

第1行:把当前目录的所有源文件列表(也就是.c和.cpp文件)放在变量 SRC_LIST中

第2行:把目录../include也就是上一层目录下的include目录包含进工程

第3行:编译的目标文件是main,用的源文件列表是变量 SRC_LIST中的文件列表

第4行:set命令我们知道,就是设置变量用的

EXECUTABLE_OUT_PATH 是cmake自带的全局变量,表示编译的可执行程序的存放位置。

PROJECT_SOURCE_DIR 也是cmake自带的全局变量,表示工程的根目录。也就是包含 "project (xxxx)"命令的CMakeLists.txt文件所在的目录。由于我们第一个CMakeLists.txt文件中包含了这句,所以其所在目录也就是工程的根目录了

总结,第4行的意思是:最终编译的可执行程序文件是main,且要存放在工程根目录下的文件目录bin中

最终的文件目录如下(注意看两个CMakeLists.txt文件所在位置)

cmake简洁教程 - 第三篇_cmake用法_02

我们开始编译

切换到build目录下,执行命令 cmake .. 意思是在当面目录执行cmake,但是CMakeLists.txt文件在上一层目录中

解释一下为什么在build目录下运行cmake?从前面几篇博客中可以看到,如果不这样做,cmake运行时会生成附带文件(例如CMakeFiles,cmake_install.cmake Makefile等文件)就会跟工程的代码文件混在一起,会对程序的目录结构造成污染。而在build目录下运行cmake .. 则生成的附带文件就只会待在build目录下,如果我们不想要这些文件了就可以直接删除build目录,很简洁

执行命令 cmake .. 和命令 make 后再到bin目录下执行命令 ./main,结果如下图(注意最终生成的main文件在bin目录下)

cmake简洁教程 - 第三篇_子目录_03

 本篇总结(1个新命令,2个新变量)

1. 命令 add_subdirectory (src) 

2. 变量 EXECUTABLE_OUT_PATH

3. 变量 PROJECT_SOURCE_DIR

至此我们已经会了基本的cmake用法,下一篇我们将会讲解更高级别的用法,编译使用动态库,静态库