CMake入门2——复杂项目的构建配置

  • 例4 多文件单目录测试
  • 例5 多文件单子目录测试
  • 例6 多目录和多级目录测试

CMake入门1——CMake与VS编译器和nmake的结合使用

例4 多文件单目录测试

此测试项目将所有的文件都放在根目录下。
在CMakeTest目录下新建demo4目录。demo4项目文件列表如下:
这里写图片描述
其中实现了算术运算的加减乘除,每个功能分别实现在各自的文件中:

int my_add(int a, int b);
int my_minus(int a, int b);
int my_multiply(int a, int b);
int my_divide(int a, int b);

然后在main.cpp中调用各个函数,代码如下:

#include 
using namespace std;

#include "add.h"
#include "minus.h"
#include "multiply.h"
#include "divide.h"

void main()
{
    cout<<"cmake test demo 4"<int a=20;
    int b=10;
    cout<"+"<"="<cout<"-"<"="<cout<"*"<"="<cout<"/"<"="<

CMakeLists.txt文件内容如下:

# CMake最低版本要求,如果低于3.10.1版本,则构建过程会被终止 
cmake_minimum_required(VERSION 3.10.1)

# 项目信息
project(demo4)

# 查找当前目录下的所有源文件,并将名称保存到DIR_SRCS变量中
aux_source_directory(. DIR_SRCS)

# 指定生成目标
add_executable(demo ${DIR_SRCS})

此配置文件中使用了一条新命令:

  • aux_source_directory:该命令会查找指定目录下的所有源文件,然后将结果存进指定变量名。这样,就不用在add_executable中列出所有源文件了,而是直接引用变量即可。

从VC命令行进入到demo4目录,然后执行cmake命令和nmake命令,即可编译出执行程序。
这里写图片描述

例5 多文件单子目录测试

此测试项目将main入口函数文放在根目录下,其他文件放在独立目录下。

新建demo5目录,使用例3中的项目文件,将main.cpp放在demo5目录下,将其他的加减乘除的相关文件放在math子目录下。然后在demo5目录和math目录下分别放一个CMakeLists.txt文件。
这里写图片描述
这里写图片描述

其中demo5目录下的CMakeLists.txt文件内容如下:

# CMake最低版本要求,如果低于3.10.1版本,则构建过程会被终止 
cmake_minimum_required(VERSION 3.10.1)

# 项目信息
project(demo5)

# 添加头文件目录
include_directories(math)

# 查找当前目录下的所有源文件,并将名称保存到DIR_SRCS变量中
aux_source_directory(. DIR_SRCS)

# 指定生成目标
add_executable(demo ${DIR_SRCS})

# 添加math子目录
add_subdirectory(math)

# 添加链接库
target_link_libraries(demo math)

在这个配置文件中,依次出现了几条新的cmake命令:

  • include_directories:头文件包含目录,因为main.cpp中使用了加减乘除函数,因此需要指明头文件目录所在之处。当然,也可以在main.cpp中包含都文件时指定目录
  • add_subdirectory:添加子目录命令,表示需要编译该子目录
  • target_link_libraries:添加要依赖的库文件,此处的math库是在子目录math中编译出来的

math目录下的CMakeLists.txt文件内容如下:

# CMake最低版本要求,如果低于3.10.1版本,则构建过程会被终止 
cmake_minimum_required(VERSION 3.10.1)

# 查找当前目录下的所有源文件,并将名称保存到DIR_SRCS变量中
aux_source_directory(. DIR_LIB_SRCS)

# 指定生成目标
add_library(math ${DIR_LIB_SRCS})

在上面这个配置文件中,出现了一条新命令:

  • add_library:将指定的文件编译为库,前面是库名称,后面是源文件

进demo5目录,然后执行cmake命令和nmake命令,即可编译出执行程序。可以看到,在math子目录下生成了一个”math.lib”的库文件。

例6 多目录和多级目录测试

本例子demo6中把加减乘除四个运算分散在不同的目录下,形成了多个目录、多级目录的形式。具体的文件布局如下图所示:
这里写图片描述
多个子目录和多级目录在用cmake来构建时的一种方式是:将所有源文件按功能或目录来分别构建为库,然后在需要用到库的地方链接上所需的一个或多个库。
对于此例来说,各目录的说明和构建方式如下:

  • demo6根目录下包括了math和divide两个目录;
  • divide目录是除法目录,由其目录中的配置文件单独构建为一个库;
  • math目录包括了add_minus和multiply两个目录;
  • add_minus目录包括加法的实现文件和减法目录minus;
  • 减法不单独构建为库,而是和加法一起,用add_minus中的配置文件构建为一个库;
  • 乘法的库也不再它自己的目录中构建,而是在math目录下构建为单独的乘法库;
  • 最后,在demo6根目录下的配置文件中构建demo.exe程序,并连接了乘法库、除法库、加减法合在一起的库;

首先,divide目录下构建除法库的配置文件比较简单,使用了 aux_source_directoryadd_library两条指令。

# CMake最低版本要求,如果低于3.10.1版本,则构建过程会被终止 
cmake_minimum_required(VERSION 3.10.1)

# 查找当前目录下的所有源文件,并将名称保存到DIR_LIB_DIVIDE_SRCS变量中
aux_source_directory(. DIR_LIB_DIVIDE_SRCS)

# 指定生成目标
add_library(lib_divide ${DIR_LIB_DIVIDE_SRCS})

其次,加减法库的构建如下:

# CMake最低版本要求,如果低于3.10.1版本,则构建过程会被终止 
cmake_minimum_required(VERSION 3.10.1)

# 查找当前目录下的所有源文件,并将名称保存到DIR_MINUS_SRCS变量中
aux_source_directory(./minus DIR_MINUS_SRCS)
# 把要编译的文件都列在此处,存入ADD_SRCS变量中
set(ADD_SRCS add.cpp)

# 指定生成目标
add_library(lib_add_minus ${ADD_SRCS} ${DIR_MINUS_SRCS})

这个也很简单,只是有3点小改变:

  • aux_source_directory指令中指定的目录为./minus,表示当前文件夹下的minus子目录,也就是把minus子目录下的减法源文件存在了DIR_MINUS_SRCS变量中
  • 使用了一条新的指令set,这也是一条用来设置变量的,不过变量放在前面,变量的值放在后面。这里指定为将当前目录下的加法实现源文件存入变量ADD_SRCS中。需注意的是,后面的文件可以列出多个各处的文件
  • add_library命令将前面的两个保存了加法和减法源文件的变量一起用来生成一个库lib_add_minus


再次math目录下的配置文件如下:

# CMake最低版本要求,如果低于3.10.1版本,则构建过程会被终止 
cmake_minimum_required(VERSION 3.10.1)

# 添加子目录
add_subdirectory(add_minus)

# 把要编译的文件都列在此处,存入DIR_MULTIPLY_SRC变量中
set(DIR_MULTIPLY_SRC multiply/multiply.cpp)

# 指定生成目标
add_library(lib_multiply ${DIR_MULTIPLY_SRC})

在这个配置文件中,将multiply目录下的乘法编译成了单独的一个库,然后添加了add_minus子目录。所用的指令都是已使用过的。

最后,根目录demo6下的配置文件如下:

# CMake最低版本要求,如果低于3.10.1版本,则构建过程会被终止 
cmake_minimum_required(VERSION 3.10.1)

# 项目信息
project(demo6)

# 添加头文件目录
include_directories(math/add_minus math/add_minus/minus math/multiply)
include_directories(divide)

# 查找当前目录下的所有源文件,并将名称保存到DIR_SRCS变量中
aux_source_directory(. DIR_SRCS)

# 指定生成目标
add_executable(demo ${DIR_SRCS})

# 添加math子目录
add_subdirectory(math)
# 添加divide子目录
add_subdirectory(divide)

# 添加链接库
target_link_libraries(demo lib_add_minus)
target_link_libraries(demo lib_multiply lib_divide)

在这个配置文件中,有几点小说明:

  • 这个根目录下的配置文件为cmake的入口配置文件,所以在其中指定了最低版本。这样其实在子目录下的配置文件中就可以不用再用cmake_minimum_required指令了
  • include_directories指令指明了头文件所在目录,一条命令中可以指定多个头文件包含目录。在实际项目中可将头文件提取到一个目录中,然后指定一个目录就可以了
  • add_subdirectory指明了dividemath两个子目录
  • target_link_libraries将各个库连接到目标程序”demo”中,此命令也可以一次指定多个库


至此,所有的工作就做好了,在命令下执行cmake命令和nmake命令,就可编译出执行程序。同时可以看到,在math子目录下生成了一个”lib_multiply.lib”库,在math/add_minus目录下生成了一个lib_add_minus.lib库,在divide目录下生成了lib_divide库。

你可能感兴趣的:(程序设计,cmake,多目录)