在上一章里面,我们用cmake做了一个最简单的项目,这一节我们尝试一写比较常见的cmake配置。
这次我们构建如下的目录结构
其中int_plus.h的代码如下:
int int_plus(const int a, const int b);
int_plus.cc的代码如下:
#include "int_plus.h"
int int_plus(const int a, const int b){
return a + b;
}
main函数的代码如下:
#include <iostream>
#include <vector>
#include <string.h>
#include "int_plus.h"
int main()
{
int a = 3;
int b = 4;
int c = int_plus(a,b);
std::cout << c << std::endl;
return 0;
}
makefiles.txt的内容如下:
# cmake 最低版本需求
cmake_minimum_required(VERSION 3.13)
# 工程名称
project(cmake_study1)
# 设置
set(CMAKE_CXX_STANDARD 11)
#3.head file path,头文件目录
include_directories(src/include)
AUX_SOURCE_DIRECTORY(src/include INCLUDE)
# 编译源码生成目标
add_executable(cmake_study src/main.cc ${INCLUDE})
add_executable配置
该配置指定了这次要编译的文件有哪些,以及编译后的可执行文件名是什么。因为编译时,编译器不会到那些文件需要,那些文件不需要,所以这里需要把所有的要编译的文件全部写进去(无论这个代码是否和main同一路径),可以以单个文件或者路径的形式写入,如果没有写而且main函数最终依赖该函数,则会报错。编译以后的可执行文件入口就是main函数。
以上面的例子来说,如果把add_executable 中的 ${INCLUDE}去掉,则会报错:
symbol(s) not found for architecture
include_directories(src/include)
这次新增了include_directories(src/include) 和 AUX_SOURCE_DIRECTORY(src DIR_SRCS)
其中
include_directories(src/include)
的作用是头文件的路径,例如在上面的例子中,main函数用到了./include/int_plus.h(以main所在目为根目录),如果没有include_directories(src/include) 那么在main中就要写
#include "include/int_plus.h"
当然,include_directories是可以包含多个文件夹的。如果有一个新的文件夹util 也被依赖,可以额外再加一个
include_directories(src/util)
AUX_SOURCE_DIRECTORY
AUX_SOURCE_DIRECTORY(src/include INCLUDE)的作用是添加源码路径。在add_executable 我们需要指定要编译的文件,当需要编译的文件特别多时,一个一个写就非常麻烦了,所以需要指定一个路径,视为源码路径。
在上面的例子中,如果没有AUX_SOURCE_DIRECTORY(src/include INCLUDE) 这一句的话,在编译时会报错
Undefined symbols for architecture x86_64:
"int_plus(int, int)", referenced from:
_main in main.cc.o
这是因为链接过程中,需要用到int_plus.cc的编译文件,但是add_executable中没有添加int_plus.cc 所以没有对其进行编译,链接时也就找不到该文件了。
同样的,如果我们有多个路径的需要加入,也可以配置多个AUX_SOURCE_DIRECTORY,例如上面的例子中,我们可以写成
AUX_SOURCE_DIRECTORY(src/include INCLUDE)
AUX_SOURCE_DIRECTORY(src SRC)
# 编译源码生成目标
add_executable(cmake_study ${SRC} ${INCLUDE})
应该注意两点:
1. AUX_SOURCE_DIRECTORY 只包含该目录下的以及文件,而不包含递归的子文件夹。
2. AUX_SOURCE_DIRECTORY(src/include INCLUDE ) 并不是把路径src/include 替换成了INCLUDE,而是在src/include路径中找到了所有非路径的文件,赋给了INCLUDE。如下代码可以证明
cmake_minimum_required(VERSION 3.13)
# 工程名称
project(cmake_study1)
# 设置
set(CMAKE_CXX_STANDARD 11)
#3.head file path,头文件目录
include_directories(src/include)
include_directories(src)
AUX_SOURCE_DIRECTORY(src/include INCLUDE)
message(${INCLUDE})
输出 src/include/int_plus.cc