当前位置: 首页 > article >正文

为没有CMake配置的第三方库添加CMake配置

1 编写CMakeLists.txt

cmake_minimum_required(VERSION 3.15)  #如果你第三方库和自己的库没有xxxConfig.cmake  
#请修改项目名称和命名空间(一般不需要)  
project("pthreads" LANGUAGES C CXX)  
set(KC_NAMESPACE "")  
#set(KC_NAMESPACE "Threads::")  
set(KC_NAMESPACE_EMPTY "")  # TODO:设置编译器标准  
set(CMAKE_C_STANDARD 99)  
set(CMAKE_C_STANDARD_REQUIRED ON)  
set(CMAKE_CXX_STANDARD 17)  
set(CMAKE_CXX_STANDARD_REQUIRED ON)  # 包含GNUInstallDirs模块是为了通过使目录可用作缓存变量来为项目提供安装到不同平台布局的灵活性。  
include(GNUInstallDirs)  # TODO:添加所有头文件  
set(KC_HEADERS  empty.h  
)  # TODO:添加所有源文件  
set(KC_SOURCE_SRC  empty.c  
)  # TODO: 生成动态链接库。  
add_library(${PROJECT_NAME} SHARED  ${KC_SOURCE_SRC}  
)  # TODO: 目标指定包含目录  
# 我们需要告诉 CMake 我们想要使用不同的包含目录,具体取决于我们是在构建库还是从已安装的位置使用它。  
# 如果我们不这样做,当 CMake 创建导出信息时,它将导出一个特定于当前构建目录的路径,并且对其他项目无效。  
# 我们可以使用 generator expressions 来指定如果我们正在构建库包括当前源目录。  
# 否则,在安装时,包含 include 目录。有关更多详细信息,请参阅“创建可重定位包”部分。  
target_include_directories(${PROJECT_NAME} PUBLIC  "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"  "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"  
)  # TODO: 指定库所依赖的库。(可选)如果指定为PUBLIC,则依赖库将被导出。  
target_link_libraries(${PROJECT_NAME} PUBLIC  
)  # TODO: 在 install(TARGETS) 命令中,将指定目标、EXPORT 名称和告诉 CMake 在何处安装目标的目的地。  
install(TARGETS ${PROJECT_NAME}  EXPORT ${PROJECT_NAME}Config # 5.a 使用“导出”选项指定导出名称。  # RUNTIME DESTINATION bin  LIBRARY DESTINATION lib # 5.b 安装库  # ARCHIVE DESTINATION lib  INCLUDES DESTINATION include # 5.c 安装一个头文件,指定导出时包含路径中要包含的路径。  
)  #使用install(FILES)命令安装头文件  
install(FILES ${KC_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})  # TODO: 安装 ${PROJECT_NAME}Config导出细节  
if ("${KC_NAMESPACE}" STREQUAL "${KC_NAMESPACE_EMPTY}")  install(EXPORT ${PROJECT_NAME}Config   # 6.a 在 5.a中指定的名称  FILE ${PROJECT_NAME}Config.cmake   # 6.b 指定文件名  DESTINATION ${CMAKE_INSTALL_PREFIX}/cmake  #cmake安装目录 ${CMAKE_INSTALL_LIBDIR}表示cmake目录位于lib\cmake中  )  
else ()  install(EXPORT ${PROJECT_NAME}Config   # 6.a 在 5.a中指定的名称  FILE ${PROJECT_NAME}Config.cmake   # 6.b 指定文件名  NAMESPACE Threads::            # 6.c 命名空间  DESTINATION ${CMAKE_INSTALL_PREFIX}/cmake   #cmake安装目录 ${CMAKE_INSTALL_LIBDIR}表示cmake目录位于lib\cmake中  )  
endif ()

2 添加一个.h和.c文件

empty.h和empty.c是防止第一节的"CMakeLists.txt"编译错误,实际不需要 。

empty.h

#include <stdio.h>  
#include <stdlib.h>  #ifndef KC_690052D6_304C_3640_9218_2B58EF66E677  
#define KC_690052D6_304C_3640_9218_2B58EF66E677  #ifdef __cplusplus  
extern "C" {  
#endif  /*__cplusplus 1*/  extern __declspec(dllexport) int __stdcall kcTest();  
#ifdef __cplusplus  
};  
#endif  /*__cplusplus 2*/  #endif  /*KC_690052D6_304C_3640_9218_2B58EF66E677*/  

empty.c

int kcTest(){  return 0;
}  

3 开始编译

编译脚本如下

chcp 65001  
set KC_PROJECT_PATH=D:\MyWork\2025\cmake_config  
cd %KC_PROJECT_PATH%  
D:  rd /S /Q build  
rd /S /Q dest  
cmake -G "NMake Makefiles" -Wno-dev -D CMAKE_BUILD_TYPE=Release -B build -S . ^  
-DCMAKE_INSTALL_PREFIX=dest  cmake --build build --config Release  cmake --install build --config Release  

编译完成后将"dest\cmake"目录复制到所在的库目录.

例如自行编译的pthreads4w库,实际的安装位置"D:/library/vs/pthreads",将"dest\cmake"拷贝至此目录。

4 修改xxxConfig.cmake

打开xxxConfig.cmake和xxxConfig-release.cmake

例如自行编译的pthreads4w库,实际的安装位置"D:/library/vs/pthreads",库名称为pthreads,没有命名空间

打开"D:/library/vs/pthreads/cmake/pthreadsConfig.cmake"

#找到  
set(_IMPORT_PREFIX "D:/MyWork/2025/cmake_config/dest")  
#修改为库实际所在的目录  
set(_IMPORT_PREFIX "D:/library/vs/pthreads")  

打开"D:/library/vs/pthreads/cmake/pthreadsConfig-release.cmake"

set_target_properties(pthreads PROPERTIES  IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/pthreads.lib"IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/pthreads.dll"
)  list(APPEND _cmake_import_check_files_for_pthreads "${_IMPORT_PREFIX}/lib/pthreads.lib" "${_IMPORT_PREFIX}/bin/pthreads.dll" )  
#修改为库实际的名称  
set_target_properties(pthreads PROPERTIESIMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/libpthreadVC3.lib"IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/pthreadVC3.dll"
)
list(APPEND _cmake_import_check_files_for_pthreads "${_IMPORT_PREFIX}/lib/libpthreadVC3.lib" "${_IMPORT_PREFIX}/bin/pthreadVC3.dll" )

至此我们为pthreads4w库配置了CMake find_package查找时所需要的配置文件

5 使用

新建一个项目,此项目需要使用到pthreads.

5.1 编写CMakeLists.txt

cmake_minimum_required(VERSION 3.15)  project(chapter01 VERSION 1.0.0 LANGUAGES C)  # TODO:查找软件包。此处就会使用到我们之前用到的配置,它会查找pthreadsConfig.cmake  
find_package(pthreads REQUIRED)  # TODO:添加所有源文件  
set(KC_SOURCE_SRC  main.c)  # TODO:生成可执行文件。  
add_executable(${PROJECT_NAME}  ${KC_SOURCE_SRC})  # TODO:导入包含目录。因为pthreadsConfig.cmake已经设置了pthreads的头文件路径,这里不需要再配置了  
target_include_directories(${PROJECT_NAME} PRIVATE  ${CMAKE_CURRENT_SOURCE_DIR})  # TODO:直接使用第一节中配置的项目名称即可链接库。注意如果有命名空间需要加上命名空间  
target_link_libraries(${PROJECT_NAME} PRIVATE  pthreads        #Threads::pthreads #如设置了命名空间名称为Threads,链接时要加上  
)  

5.2 添加编译参数使CMakeLists.txt能够正确的找到pthreads

pthreads_DIR的含义:pthreads为第一节中配置的项目名称,"_DIR"为固定值.

pthreads_DIR需要指向到xxxConfig.cmake所在的目录,而不是库安装目录 .

添加"pthreads_DIR:PATH=D:/library/vs/pthreads/cmake"至Vs Code、CLion、Visual Studio等开发工具即可使用。

如果使用命令行用以下方式添加

cmake -G "NMake Makefiles" -Wno-dev -D CMAKE_BUILD_TYPE=Debug -B build -S . ^  
-Dpthreads_DIR:PATH=D:/library/vs/pthreads/cmake  cmake --build build --config Debug  cmake --install build --config Debug  

上述操作完成后在Vs Code、CLion、Visual Studio中均可正确找到头文件和库文件。

相关文章:

为没有CMake配置的第三方库添加CMake配置

1 编写CMakeLists.txt cmake_minimum_required(VERSION 3.15) #如果你第三方库和自己的库没有xxxConfig.cmake #请修改项目名称和命名空间&#xff08;一般不需要&#xff09; project("pthreads" LANGUAGES C CXX) set(KC_NAMESPACE "") #set(K…...

Linux驱动编程 - seq_open、single_open使用方法

目录 前言: 一、seq_xxx 1、seq_xxx 函数介绍 1.1 seq_open 1.2 seq_read 1.3 seq_lseek 1.4 seq_release 1.5 格式化输出函数 2、seq_open 实例 二、single_xxx 函数 1、single_xxx 函数介绍 1.1 single_open 1.2 single_start 1.3 single_next 1.4 single_stop…...

N列股票收盘价为起点的马科维茨(Markowitz)均值—方差理论

1. 数据准备与收益率计算 输入数据&#xff1a; 假设你有一个矩阵&#xff0c;每一列代表一只股票的历史收盘价序列。每一行对应一个时间点的收盘价。 计算收益率&#xff1a; 马科维茨理论要求使用资产的收益率而非价格。常用的收益率计算方法有对数收益率或简单收益率。 2.…...

【嵌入式学习2】函数

目录 ## 函数 ## 函数分类 ## 函数定义 1、无参数无返回值 2、有参数无返回值 3、有参数有返回值 ## 函数声明 ## 局部变量和全局变量 ## 多文件编程 如何避免把同一个头文件 include 多次&#xff0c;或者头文件嵌套包含&#xff1f; 命令行编译文件 头文件包含的…...

模式搜索+扩散模型:FlowMo重构图像Token化的技术革命

图像Token化作为现代生成式AI系统的核心技术&#xff0c;长期面临对抗性训练不稳定、潜在空间冗余等挑战。斯坦福大学李飞飞与吴佳俊团队提出的FlowMo&#xff08;Flow towards Modes&#xff09;创新性地融合模式搜索与扩散模型&#xff0c;在多个关键维度突破传统方法局限&am…...

mac brew 安装的php@7.4 打开redis扩展

1. 找到php7.4的pecl目录 一般在这个位置 cd /usr/local/Cellar/php7.4/7.4.33_8/pecl/20190902 ls 一下 有个 redis.so 于是 直接去php.ini编辑了 php.ini的路径 vim /usr/local/etc/php/7.4/php.ini 把938行添加进去 然后重启一下 php7.4 brew services restart ph…...

OSPF多区域通信

作业要求: 1、多区域0SPF area 0、area10、are20 2、AR5、AR6作为stub区&#xff0c;使用环回接口与Pc1进行通信 第一步&#xff1a;为各端口配置IP地址 AR1: <Huawei>sys [Huawei]int g0/0/0 [Huawei-GigabitEthernet0/0/0]ip add 5.5.5.1 24 [Huawei-GigabitEther…...

C++模板编程与元编程面试题及参考答案(精选100道题)

目录 解释 C++ 模板的实例化过程,显式实例化与隐式实例化的区别 模板函数在不同翻译单元中的 ODR(单一定义规则)问题 模板参数推导失败的可能场景及解决方法 模板函数中 auto 返回类型的推导规则 如何限制模板函数仅接受特定类型的参数?(非 C++20 概念场景) 函数模板…...

括弧匹配检验(信息学奥赛一本通-1354)

【题目描述】 假设表达式中允许包含两种括号&#xff1a;圆括号和方括号&#xff0c;其嵌套的顺序随意&#xff0c;如&#xff08;&#xff3b; &#xff3d;&#xff08;&#xff09;&#xff09;或&#xff3b;&#xff08;&#xff3b; &#xff3d;&#xff3b; &#xff3…...

三、重学C++—C语言内存管理

上一章节&#xff1a; 二、重学C—C语言核心-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/146191640?spm1001.2014.3001.5502 本章节代码&#xff1a; cPart2 CuiQingCheng/cppstudy - 码云 - 开源中国https://gitee.com/cuiqingcheng/cppstudy/tree/…...

算法题(105):小猫爬山

审题&#xff1a; 本题需要我们找出将n个小猫放在有限重的缆车上运下山所需的最小缆车数 时间复杂度分析&#xff1a;本题的数据量小于等于18&#xff0c;所以我们在做好剪枝的前提下可以使用深度优先搜索解题 思路&#xff1a; 方法一&#xff1a;dfs 搜索策略&#xff1a;将小…...

C语言-适配器模式详解与实践

文章目录 C语言适配器模式详解与实践1. 什么是适配器模式&#xff1f;2. 为什么需要适配器模式&#xff1f;3. 实际应用场景4. 代码实现4.1 UML 关系图4.2 头文件 (sensor_adapter.h)4.3 实现文件 (sensor_adapter.c)4.4 使用示例 (main.c) 5. 代码分析5.1 关键设计点5.2 实现特…...

线程的pthread_create、pthread_join、pthread_exit、pthread_detach函数

线程的创建&#xff08;pthread_create&#xff09; pthread_t tid;//本质是unsigned long类型&#xff0c;打印时得到的是该线程的虚拟地址int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine)(void*), void *arg ); pthread_t *thre…...

测试专项4:AI算法测试在测试行业中,该如何定位自己自述

这岗位到底干啥的&#xff1f; 打个比方&#xff1a; 你就像AI模型的“质检员产品经理风险顾问”三合一。 质检员&#xff1a; 别人造了个AI模型&#xff08;比如人脸识别系统&#xff09;&#xff0c;你不能光看它实验室成绩好&#xff0c;得把它丢到现实里折腾&#xff1a;…...

QT-LINUX-Bluetooth蓝牙开发

BlueToothAPI QT-BlueToothApi Qt Bluetooth 6.8.2 官方提供的蓝牙API不支持linux。 D-Bus的API实现蓝牙 确保系统中安装了 BlueZ(版本需≥5.56),并且 Qt 已正确安装并配置了 D-Bus 支持。 默默看了下自己的版本.....D-BUS的API也不支持。 在 D-Bus 中,org 目录是 D-Bus…...

【经验总结】AUTOSAR架构下NvMBlock无效问题分析

目录 前言 正文 1.问题描述 2.问题原因 3.深入分析 3.1NvM_InvalidateNvBlock分析 3.2NvBlock无效后NvM_ReadBlock行为分析 3.3NvBlock无效后NvM_WriteBlock行为分析 4.总结 前言 最近在做所有NvMBlock测试的时候,发现一个NvMBlock始终无法测试成功(写入Block值 --&…...

STM32 的tf卡驱动

基于STM32的TF卡驱动的基本实现步骤和相关代码示例,主要使用SPI接口来与TF卡进行通信。 硬件连接 将TF卡的SPI接口与STM32的SPI引脚连接,通常需要连接SCK(时钟)、MOSI(主出从入)、MISO(主入从出)和CS(片选)引脚。 软件实现 初始化SPI 配置SPI的工作模式、时钟频率…...

stress-ng命令详解

stress-ng 是一款功能强大的 Linux 系统压力测试工具&#xff0c;能够模拟多种复杂负载场景&#xff0c;覆盖 CPU、内存、磁盘 I/O、进程调度等核心资源&#xff0c;帮助开发者验证系统在高负载下的稳定性与性能表现。以下是其核心功能、参数解析及实战案例。 一、工具简介与安…...

【C语言系列】数据在内存中存储

数据在内存中存储 一、整数在内存中的存储二、大小端字节序和字节序判断2.1什么是大小端&#xff1f;2.2练习2.2.1练习12.2.2练习22.2.3练习32.2.4练习42.2.5练习52.2.6练习6 三、浮点数在内存中的存储3.1练习3.2浮点数的存储3.2.1 浮点数存的过程3.2.2 浮点数取的过程 3.3题目…...

【中文翻译】第12章-The Algorithmic Foundations of Differential Privacy

由于GitHub项目仅翻译到前5章&#xff0c;我们从第6章开始通过大语言模型翻译&#xff0c;并导出markdown格式。 大模型难免存在错漏&#xff0c;请读者指正。 教材原文地址&#xff1a;https://www.cis.upenn.edu/~aaroth/Papers/privacybook.pdf 12 其他模型 到目前为止&…...

图解模糊推理过程(超详细步骤)

我们前面已经讨论了三角形、梯形、高斯型、S型、Z型、Π型6种隶属函数&#xff0c;下一步进入模糊推理阶段。 有关六种隶属函数的特点在“Pi型隶属函数&#xff08;Π-shaped Membership Function&#xff09;的详细介绍及python示例”都有详细讲解&#xff1a;https://lzm07.b…...

datawhale组队学习-大语言模型-task5:主流模型架构及新型架构

目录 5.3 主流架构 5.3.1 编码器-解码器架构 5.3.2 因果解码器架构 5.3.3 前缀解码器架构 5.4 长上下文模型 5.4.1 扩展位置编码 5.4.2 调整上下文窗口 5.4.3 长文本数据 5.5 新型模型架构 5.5.1 参数化状态空间模型 5.5.2 状态空间模型变种 5.3 主流架构 在预训…...

为什么后端路由需要携带 /api 作为前缀?前端如何设置基础路径 /api?

一、为什么后端路由需要携带 /api 作为前缀&#xff1f; 1. 区分 API 端点与其他路由 在 Web 应用程序中&#xff0c;后端不仅需要处理 API 请求&#xff0c;还可能需要处理静态资源&#xff08;如 HTML、CSS、JS 文件&#xff09;或其他服务&#xff08;如 WebSocket&#x…...

C++ 关系运算符重载和算术运算符重载的例子,运算符重载必须以operator开头

在C中&#xff0c;运算符重载允许为用户定义的类型&#xff08;类或结构体&#xff09;赋予某些内置运算符的功能。下面是一个关于关系运算符重载&#xff08;&#xff09;和算术运算符重载&#xff08;&#xff09;的简单例子。 示例&#xff1a;复数类的运算符重载 将创建一…...

建造者模式 (Builder Pattern)

建造者模式 (Builder Pattern) 是一种创建型设计模式,它将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。 一、基础 1.1 意图 将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。 1.2 适用场景 当创建复杂对象的算法应该…...

MCU vs SoC

MCU&#xff08;Microcontroller Unit&#xff0c;单片机&#xff09;和SoC&#xff08;System on Chip&#xff0c;片上系统&#xff09;是两种不同的芯片类型&#xff0c;尽管它们都实现了高度集成&#xff0c;但在设计目标、功能复杂性和应用场景上存在显著差异。以下是两者…...

RAG 架构地基工程-Retrieval 模块的系统设计分享

目录 一、知识注入的关键前奏——RAG 系统中的检索综述 &#xff08;一&#xff09;模块定位&#xff1a;连接语言模型与知识世界的桥梁 &#xff08;二&#xff09;核心任务&#xff1a;四大关键问题的协调解法 &#xff08;三&#xff09;系统特征&#xff1a;性能、精度…...

(C语言)习题练习 sizeof 和 strlen

sizeof 上习题&#xff0c;不知道大家发现与上一张的习题在哪里不一样嘛&#xff1f; int main() {char arr[] "abcdef";printf("%zd\n", sizeof(arr));printf("%zd\n", sizeof(arr 0));printf("%zd\n", sizeof(*arr));printf(&…...

Unity Animation的其中一种运用方式

Animation是Unity的旧的动画系统&#xff0c;先说目的&#xff0c;其使用是为了在UI中播放动效&#xff0c;并且在动效播放结束后接自定义事件而设计的 设计的关键点在于&#xff0c;这个脚本不是通过Animation直接播放动画片段&#xff0c;而是通过修改AnimationState的nor…...

湖北楚大夫

品牌出海已成为众多企业拓展业务、提升竞争力的关键战略。楚大夫(chudafu.com)作为一家专注于品牌出海、海外网络营销推广以及外贸独立站搭建的公司&#xff0c;凭借其专业、高效、创新的服务模式&#xff0c;致力于成为中国企业走向国际市场的坚实后盾与得力伙伴。楚大夫通过综…...