栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Windows下使用cmake 组织工程,编译静态库、动态库,导入第三方库,编译工程

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Windows下使用cmake 组织工程,编译静态库、动态库,导入第三方库,编译工程

Windows下使用cmake 组织工程,编译静态库、动态库,导入第三方库,编译工程
  • 1 使用主工程的CMakeLists.txt生成所有目标
    • 1.1 构建静态库并进行编译
    • 1.2 构建动态库并进行编译
  • 2 将main.cpp外的其他文件作为子工程
    • 2.1 构建静态链接库并编译
    • 2.2 构建动态链接库并编译
  • 3 首先将main.cpp外的其他文件编译为库,然后将其作为第三方库导入
    • 3.1 构建静态链接库并导入
      • 2.1.1 编译静态链接库
      • 3.1.2 导入编译的库并编译主工程
    • 3.2 构建动态链接库并导入
      • 3.2.1 编译动态链接库
      • 3.2.2 导入编译的库并编译主工程

目标:编译一个含有三个文件的工程,使用三种方法:
1、使用主工程的CMakeLists.txt生成所有目标
2、将main.cpp外的其他文件作为子工程
2、首先将main.cpp外的其他文件编译为库,然后将其作为第三方库导入

1 使用主工程的CMakeLists.txt生成所有目标 1.1 构建静态库并进行编译

工程结构:

CMakeLists.txt

cmake_minimum_required(VERSION 3.10.0)
# 最低版本要求 cmake 构建工具小于3.10.0将报错
 
project(main)
# 工程项目名称
 
set(MOD_MY_CALCULATION_PATH ${CMAKE_SOURCE_DIR}/my_calculation)
# 设置一个变量标记路径
# ${CMAKE_SOURCE_DIR} 这个取CMake自带宏里面的路径 就是这个CMakeLists.txt所在的路径
 
aux_source_directory(${MOD_MY_CALCULATION_PATH} MOD_MY_CALCULATION_SRC)
# ${} 固定的范式,取变量 MOD_MY_CALCULATION_PATH 里面的值,这里为 ${CMAKE_SOURCE_DIR}/my_calculation
# MOD_MY_CALCULATION_SRC自定义的一个变量
# 整条语句将对 ${CMAKE_SOURCE_DIR}/my_calculation 的源码*.cpp 和*.c 文件 输出到变量 MOD_MY_CALCULATION_SRC
 
add_library(my_calculation STATIC ${MOD_MY_CALCULATION_SRC}) # 构建静态库
# 将所有的源文件归档成lib 这一句将会在build下生成lib
 
# --------------上面的语句就已经能够生成静态库------------------
aux_source_directory(${CMAKE_SOURCE_DIR} RP_ALL_SRC)
# 这里对 ${CMAKE_SOURCE_DIR} 也就是当前CMakeList.txt 目录下的*.cpp输出到变量
# RP_ALL_SRC (RP_ALL_SRC 意为顶层目录所有源码)
add_executable(main ${RP_ALL_SRC})
 
target_link_libraries(main my_calculation)  
#为生成目标添加编译的库(my_calculation) 可以是多个 比如 target_link_libraries(main lib1 lib2) 
#这里因为是在同一个CMakeLists.txt中 所以lib会被识别并找到,这里默认构建了其生成的依赖关系

my_calculation.h

#pragma once

int my_sum(int n);

my_calculation.cpp 定义一个函数,计算0到输入值之间所有正整数的和

#include "my_calculation.h"

int my_sum(int n)
{
    int sum = 0;
    for (; n > 0; n--)
    {
        sum += n;
    }
    return sum;
}

main.cpp

#include 
#include "my_calculation/my_calculation.h"
using namespace std;

int main()
{
    int num = 100;

    cout << my_sum(num) << endl;

    system("pause");
    return 0;
}

编写一个批处理文件进行自动编译:

rmdir /s/q build 
mkdir build
cd build
cmake -G "MinGW Makefiles" ..
cmake --build .
cd ..

双击compile.bat,运行结果:

计算0-100之间所有整数之和:

1.2 构建动态库并进行编译

只需将CMakeLists.txt中构建静态链接库时STATIC改为SHARED,运行结果:

如果没有.dll动态链接库,运行main.exe将报错:

2 将main.cpp外的其他文件作为子工程

工程结构:

2.1 构建静态链接库并编译

sub目录下CMakeLists.txt

cmake_minimum_required(VERSION 3.10.0) #cmake的 最低版本
 
project(my_calculation)
 
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} my_calculation_ALL_SRC)
# 遍历当前cmake下的所有*.c和*.cpp文件 输入到变量 my_calculation_ALL_SRC
add_library(my_calculation STATIC ${my_calculation_ALL_SRC})
#引用当前所有c和cpp文件 生成一个 静态链接库

根目录下CMakeLists.txt

cmake_minimum_required(VERSION 3.10.0)
# 最低版本要求 cmake 构建工具小于3.10.0将报错
 
project(main)
# 工程项目名称
 
aux_source_directory(${CMAKE_SOURCE_DIR} RP_ALL_SRC)
# 这里对 ${CMAKE_SOURCE_DIR} 也就是当前CMakeList.txt 目录下的*.cpp输出到变量
# RP_ALL_SRC (ROOTPATH_ALL_SRC 意为顶层目录所有源码)

add_subdirectory(sub) # 添加子项

add_executable(main ${RP_ALL_SRC})
 
target_link_libraries(main my_calculation)  
#为生成目标添加一个库 可以是多个 比如 target_link_libraries(main lib1 lib2)

此时注意修改main.cpp中包含路径:

#include "sub/my_calculation.h"

main.cpp

#include 
#include "sub/my_calculation.h"
using namespace std;

int main()
{
    int num = 100;

    cout << my_sum(num) << endl;

    system("pause");
    return 0;
}

运行结果:

2.2 构建动态链接库并编译

sub目录下CMakeLists.txt

cmake_minimum_required(VERSION 3.10.0) #cmake的 最低版本
 
project(my_calculation)
 
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} my_calculation_ALL_SRC)
# 遍历当前cmake下的所有*.c和*.cpp文件 输入到变量 my_calculation_ALL_SRC
 
add_library(my_calculation SHARED ${calculation_ALL_SRC})
#引用当前所有c和cpp文件 生成一个 静态链接库

根目录下CMakeLists.txt与2.1中相同
在根目录下compail.bat批处理命令中添加下面一行,将.dll文件拷贝到build目录中

copy sub*.dll .

compail.bat

rmdir /s/q build
mkdir build
cd build
cmake -G "MinGW Makefiles" ..
cmake --build .
copy sub*.dll .
cd ..

运行结果:

3 首先将main.cpp外的其他文件编译为库,然后将其作为第三方库导入 3.1 构建静态链接库并导入 2.1.1 编译静态链接库

工程结构:

此时lib目录为空,my_calculation目录也可以不是工程下的子目录,我们只需要将my_calculation下的代码编译为库,将其放在lib文件夹中,并作为第三方库导入到主工程中

首先编译my_calculation静态库,my_calculation目录下CMakeLists.txt为:

cmake_minimum_required(VERSION 3.10)

project(my_calculation)

add_library(my_calculation STATIC my_calculation.cpp)

编译结果:

生成静态链接库.a文件,将其复制到lib目录下:

接下来不用去关注my_calculation目录了,但注意要将my_calculation.h头文件复制一份到inc目录下,我们之后将会把这个目录添加到工程的头文件包含目录。

3.1.2 导入编译的库并编译主工程

主工程根目录下CMakeLists.txt

cmake_minimum_required(VERSION 3.10.0)
# 最低版本要求 cmake 构建工具小于3.10.0将报错
 
project(main)
# 工程项目名称
 
aux_source_directory(${CMAKE_SOURCE_DIR} RP_ALL_SRC)
# 这里对 ${CMAKE_SOURCE_DIR} 也就是当前CMakeList.txt 目录下的*.cpp输出到变量
# RP_ALL_SRC (ROOTPATH_ALL_SRC 意为顶层目录所有源码)

include_directories(inc) # 添加头文件包含目录

link_directories(lib) # 添加链接库文件目录  注意,此行必须在add_executable前,否则编译器在生成main.exe时将无法找到库文件

add_executable(main ${RP_ALL_SRC})
 
target_link_libraries(main my_calculation)  
#为生成目标添加一个库 可以是多个 比如 target_link_libraries(main lib1 lib2)

运行结果:

3.2 构建动态链接库并导入 3.2.1 编译动态链接库

工程结构:

工程结构与编译静态链接库时相同,将my_calculation目录下CMakeLists.txt中add_library中参数STATIC改为SHARED

cmake_minimum_required(VERSION 3.10)

project(my_calculation)

add_library(my_calculation SHARED my_calculation.cpp)

运行结果:

将编译出的.dll动态链接库复制到主工程根目录下的lib文件夹中:

同样,接下来不需要再关注my_calculation目录

3.2.2 导入编译的库并编译主工程

主工程的CMakeLists.txt文件与2.1中相同
在编译后必须将lib目录下的.dll文件复制到build目录下,否则main.exe运行将会报错。因此在主工程的compile.bat中增加一行:

copy ..lib*.dll .

主工程中的compile.bat

rmdir /s/q build
mkdir build
cd build
cmake -G "MinGW Makefiles" ..
cmake --build .
copy ..lib*.dll .
cd ..

运行结果:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/302407.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号