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

本文详细介绍了如何在Windows环境下使用CMake组织工程,包括如何构建静态库和动态库,如何将其他文件作为子工程处理,以及如何将编译后的库作为第三方库导入并编译主工程。通过具体的工程结构和CMakeLists.txt配置,展示了编译过程和结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


目标:编译一个含有三个文件的工程,使用三种方法:
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;
    
### 如何在 CMake 中配置和引入第三方 DLL 库 #### 配置环境变量与路径设置 为了使 CMake 能够找到并正确处理外部的 DLL 和其对应的库文件,在构建脚本中需要指明这些资源的位置。通常情况下,这涉及到设定特定于项目的查找路径以及确保编译器能够访问必要的头文件。 对于给定结构化的 `3rdparty` 文件夹[^2]: ```plaintext 3rdparty ├─bin │ test.dll ├─cmake │ test.cmake ├─include │ test.hpp └─lib ├─Debug │ test.lib └─Release test.lib ``` 可以采用如下方式来定义相应的路径: ```cmake set(TEST_ROOT ${CMAKE_SOURCE_DIR}/3rdparty) # 设置包含目录 target_include_directories(main PRIVATE ${TEST_ROOT}/include) # 定义链接选项以支持 Windows 下动态加载 DLLs if(MSVC OR MINGW) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /NODEFAULTLIB:libcmt") endif() ``` 上述代码片段设置了测试库的根目录,并将其下的 `include` 子目录作为目标可执行程序的目标私有包含路径的一部分;同时也针对 MSVC 或 MinGW 编译环境下调整了链接标志位,防止潜在冲突发生。 #### 查找包及其依赖关系管理 利用 `find_package()` 函数可以帮助定位已安装软件包的存在与否,并自动导入它们所提供的功能模块。如果存在自定义 `.cmake` 文件用于描述如何集成某个特定版本的库,则可以通过提供提示参数 (`HINTS`) 来加速搜索过程。 ```cmake find_package(test REQUIRED HINTS "${TEST_ROOT}/cmake") ``` 这段指令尝试寻找名为 "test" 的组件,并告知 CMake 去哪里查看额外的帮助信息——即位于 `${TEST_ROOT}/cmake` 目录内的辅助脚本。 #### 连接静态/共享库至最终产物 一旦确认所需的所有部件都已被成功识别出来之后,就可以继续完成最后一步操作:把实际的二进制形式(无论是 `.a`,`.so`还是`.dll/.lib`)附加到应用程序上去了。这里需要注意区分不同平台上的差异之处,比如 Linux 上面习惯用 `.so` 表示共享对象而 Windows 则更倾向于使用 `.dll`. 当涉及 Windows 平台上的 DLL 时,除了显式声明要连接哪个库之外,还需要考虑运行期间怎样让操作系统知道去哪里获取那些被调用者所依赖的服务端点。一种常见做法是在部署阶段将所有关联好的 DLL 放置于同一级工作空间内或是系统的 PATH 环境变量覆盖范围内。 ```cmake # 对应 Debug 版本 if (MSVC AND CMAKE_BUILD_TYPE MATCHES Debug) target_link_libraries(main PRIVATE optimized ${TEST_ROOT}/lib/Release/test.lib debug ${TEST_ROOT}/lib/Debug/test.lib) else() target_link_libraries(main PRIVATE test) endif() # 复制 DLL 至输出目录 file(COPY ${TEST_ROOT}/bin/${CMAKE_SHARED_LIBRARY_PREFIX}test${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION $<TARGET_FILE_DIR:main>) ``` 此部分逻辑首先判断当前使用的工具链是否为 Microsoft Visual Studio 及其变体之一,并且检查构建模式是不是调试态。如果是的话就分别指定优化版和调试版各自的 LIB 文件位置;如果不是则默认按照常规流程处理即可。另外还包含了将对应架构下生成的 DLL 自动复制到主程序所在的工作区里去的功能实现。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值