由于cmake内容较多,篇幅较长,为了不让人疲倦,分成了多篇博客,全部博客链接如下
cmake简洁教程 - 第一篇_YZF_Kevin的博客-CSDN博客
cmake简洁教程 - 第二篇_YZF_Kevin的博客-CSDN博客
cmake简洁教程 - 第三篇_YZF_Kevin的博客-CSDN博客
cmake简洁教程 - 第四篇_cmake全局变量_YZF_Kevin的博客-CSDN博客
cmake简洁教程 - 第五篇_YZF_Kevin的博客-CSDN博客
这是博客cmake简洁教程的第三篇,主要介绍如何更"正规"地使用cmake
一般来说,正规的工程会符合以下几条规则
1. 把所有的头文件放在子目录include中
2. 把所有的源文件放在子目录src中
3. 把要编译的目标文件(可执行程序,库文件)放在子目录bin中
4. 把编译的临时文件放在子目录build中,这样就不会都产生在工程根目录下碍眼了
接着上篇博客的例子,我们再次改造,如下图所示(按照上面的规则1,2,3,4,把文件重新挪了下位置)
这种情况下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文件所在位置)
我们开始编译
切换到build目录下,执行命令 cmake .. 意思是在当面目录执行cmake,但是CMakeLists.txt文件在上一层目录中
解释一下为什么在build目录下运行cmake?从前面几篇博客中可以看到,如果不这样做,cmake运行时会生成附带文件(例如CMakeFiles,cmake_install.cmake Makefile等文件)就会跟工程的代码文件混在一起,会对程序的目录结构造成污染。而在build目录下运行cmake .. 则生成的附带文件就只会待在build目录下,如果我们不想要这些文件了就可以直接删除build目录,很简洁
执行命令 cmake .. 和命令 make 后再到bin目录下执行命令 ./main,结果如下图(注意最终生成的main文件在bin目录下)
本篇总结(1个新命令,2个新变量)
1. 命令 add_subdirectory (src) 添加一个cmake的子目录,且该目录下一定有CMakeLists.txt文件,请构建之
2. 变量 EXECUTABLE_OUT_PATH cmake自带的全局变量,表示编译的可执行程序的存放位置
3. 变量 PROJECT_SOURCE_DIR cmake自带的全局变量,表示工程的根目录
至此我们已经会了基本的cmake用法,下一篇我们将会讲解更高级别的用法,编译使用动态库,静态库