天天看点

CMake使用详解二(多文件编译)1 同一目录,多个源文件2 多个目录,多个源文件3 CMake使用小结

文章目录

  • 1 同一目录,多个源文件
    • 1.1 创建2个源文件
    • 1.2 编写CMakeLists.txt
    • 1.3 编译项目
  • 2 多个目录,多个源文件
    • 2.1 在不同的目录下新建源代码
    • 2.2 编写CMakeLists.txt
      • 2.2.1 根目录中的 CMakeLists
      • 2.2.2 子目录中的 CMakeLists
    • 2.3 编译运行
  • 3 CMake使用小结

续上一篇:CMake使用详解一(单文件编译)

CMake使用详解二(多文件编译)1 同一目录,多个源文件2 多个目录,多个源文件3 CMake使用小结

1 同一目录,多个源文件

1.1 创建2个源文件

mathPowerDemo2

文件夹中新建两个cpp文件:

$ mkdir mathPowerDemo2
$ cd mathPowerDemo2
$ gedit main.cpp
$ gedit power.cpp
$ gedit power.h
           

main.cpp

中源代码为:

#include <stdio.h>
#include <stdlib.h>
#include "power.h"			//特别注意自己定义的函数头文件需要用引号括起来

int main(int argc, char *argv[])
{
    if (argc < 3){
        printf("Usage: %s base exponent \n", argv[0]);
        return 1;
    }
    double base = atof(argv[1]);
    int exponent = atoi(argv[2]);
    double result = power(base, exponent);
    printf("%g ^ %d is %g\n", base, exponent, result);
    return 0;
}
           

power.cpp

中源代码为:

#include "power.h"			//特别注意自己定义的函数头文件需要用引号括起来

double power(double base, int exponent)
{
    int result = base;
    int i;
    
    if (exponent == 0) {
        return 1;
    }
    
    for(i = 1; i < exponent; ++i){
        result = result * base;
    }
    return result;
}
           

同时编写

power.h

#ifndef POWER_H
#define POWER_H
double power(double base, int exponent);

#endif
           

此时,

/mathPowerDemo2

文件夹中的文件为:

CMake使用详解二(多文件编译)1 同一目录,多个源文件2 多个目录,多个源文件3 CMake使用小结

1.2 编写CMakeLists.txt

新建CMakeLists.txt

$ gedit CMakeLists.txt
           

CMakeLists.txt

中输入:

# CMake最低版本要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (mathPowerDemo2)
# 制定生成目标
add_executable(mathPowerDemo2 main.cpp power.cpp)
           

如果同一个文件夹下,特别多的源文件怎么办呢?

使用

aux_source_directory

命令

该命令会查找制定目录下所有的源文件,然后把结果保存进指定的变量名,语法格式为:

对应的

CMakeLists.txt

修改为:

# CMake最低版本要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (mathPowerDemo2)
# 指定当前目录下的源文件,保存到<ALL_SRCS>变量中
aux_source_directory(. ALL_SRCS)
# 制定生成目标
add_executable(mathPowerDemo2 ${ALL_SRCS})
           

1.3 编译项目

$ cmake .
$ make 
           

得到可执行文件

mathPowerDemo2

,运行测试:

[email protected]:~/Documents/mathPowerDemo2$ ./mathPowerDemo2 9 2
9 ^ 2 is 81
           

2 多个目录,多个源文件

2.1 在不同的目录下新建源代码

$ mkdir mathPowerDemo3
$ cd mathPowerDemo3
$ gedit main.cpp
$ mkdir math
$ cd math
$ gedit power.cpp
$ gedit power.h
           

此时的文件目录结构为:

./mathPowerDemo3
    |
    +--- main.cpp
    |
    +--- math/
          |
          +--- power.cpp
          |
          +--- power.h
           

2.2 编写CMakeLists.txt

对于这种情况,需要分别在项目根目录 mathPowerDemo3 和 math 目录里各编写一个 CMakeLists.txt 文件。为了方便,我们可以先将 math 目录里的文件编译成静态库再由 main 函数调用。

2.2.1 根目录中的 CMakeLists

返回上一层目录,编辑根目录中的 CMakeLists.txt :

cd ..
gedit  CMakeLists.txt
           

输入

cmake_minimum_required (VERSION 2.8)
project (mathPowerDemo3)
aux_source_directory(. ALL_SRCS)			# 添加当前目录下所有的源文件
add_subdirectory(math)						# 添加math子目录
add_executable(mathPowerDemo3 ${ALL_SRCS})	# 指定生成目标,注意这里要用${ALL_SRCS}!!!
target_link_libraries(mathPowerDemo3 power)	# 添加链接库,power是在math子目录的CMakeLists中定义的
           

第4行,使用命令

add_subdirectory

指明本项目包含一个子目录 math,这样 math 目录下的 CMakeLists.txt 文件和源代码也会被处理 。

第6行,使用命令

target_link_libraries

指明可执行文件 main 需要连接一个名为 power 的链接库 。

2.2.2 子目录中的 CMakeLists

进入子目录

cd math
gedit CMakeLists.txt
           

编辑子目录中的 CMakeLists.txt,这里不需要再重复指定版本号等等,只需要把文件都包含进来,然后生成一个链接库就行了,子目录中的CMakeLists本质上是去生成一个链接库。

aux_source_directory(. LIB_SRCS)			# 添加当前目录下所有的源文件
add_library (power ${LIB_SRCS})				# 当前目录下的文件生成一个链接库
           

在该文件中使用命令

add_library

将 src 目录中的源文件编译为静态链接库。

2.3 编译运行

在主目录下直接用

cmake .

make

命令就可以编译了,不需要进入math子文件夹。

$ cd ..
$ cmake .
$ make 
           

运行测试:

$ ./mathPowerDemo2 2 10
2 ^ 10 is 1024
           

测试成功

3 CMake使用小结

  1. 使用

    aux_source_directory

    命令把某个目录下的所有文件名保存到一个变量中
    aux_source_directory(<dir> <variable>)					# 添加<dir>目录下所有的文件,保存到<variable>变量中
               
  2. 使用

    add_executable

    命令把一系列文件编译成

    projectName

    这个目标文件
  3. 如果是多个目录编译,首先使用

    add_subdirectory

    命令需要把目录包含进来,然后使用

    target_link_libraries

    命令,把子项目链接到对应的主项目
    add_subdirectory(<sub_dir>)								# 添加一个子目录<sub_dir>
    target_link_libraries(projectName sub_projectName)		# 把子目录的<sub_projectName>库链接到<projectName>主库中
               
  4. 在多目录编译中,还需要在子目录的

    CMakeLists.txt

    中设置好链接库
    aux_source_directory(. <variable>)						# 添加子目录当前目录下所有的源文件,<.>表示当前目录
    add_library(sub_projectName ${variable})				# 当前目录下的文件生成一个链接库
               

继续阅读