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

news2025/3/26 4:32:05

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 PROPERTIES
	IMPORTED_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中均可正确找到头文件和库文件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2320671.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

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

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

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++—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;将小…

线程的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;…

【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 主流架构 在预训…

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…

框架的CVE漏洞利用 php类 java类 手工操作和自动化操作蓝队分析漏洞利用的流量特征

前言 php重要框架和基本的识别特征 php的主要是 tp框架 和 laravel 当然还有 yii等 tp的主要特征 1\报错信息&#xff1a; 2、图标 3、请求头 Laravel特征 1、报错信息 2、请求头 php框架CVE利用 lavarvel 工具 https://github.com/zhzyker/CVE-2021-3129 https://git…

【算法day19】括号生成——数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

括号生成 https://leetcode.cn/problems/generate-parentheses/description/ 数字 n 代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且 有效的 括号组合。 左括号数必须大于右括号数&#xff0c;且小于等于n class Solution { publ…

Qt5.15.2实现Qt for WebAssembly与示例

目录 1.什么是Qt for WebAssembly&#xff1f; 1.1 什么是 WebAssembly&#xff1f; 1.2 WebAssembly 的优势 1.3 什么是 Qt for WebAssembly&#xff1f; 1.4 Qt for WebAssembly 的特点 1.5 编译过程 1.6 运行时环境 注意&#xff01;&#xff01;&#xff01;注意&am…

好吧好吧,看一下达梦的模式与用户的关系

单凭个人感觉&#xff0c;模式在达梦中属于逻辑对象合集&#xff0c;回头再看资料 应该是一个用户可以对应多个模式 问题来了&#xff0c;模式的ID和用户的ID一样吗&#xff1f; 不一样 SELECT USER_ID,USERNAME FROM DBA_USERS WHERE USERNAMETEST1; SELECT ID AS SCHID, NA…

HOW - DP 动态规划系列(三)(含01背包问题)

目录 一、01背包问题最直接的暴力解法动态规划解法 二、完全背包 通过几个算法的学习&#xff0c;理解和掌握动态规划来解决背包问题。 一、01背包问题 对于面试的话&#xff0c;掌握01背包和完全背包就够用了&#xff0c;最多可以再来一个多重背包。 如果这几种背包分不清&…

在linux服务器部署Heygem

前言&#xff1a; Heygem官方文档上提供了基于windwos系统的安装方案。在实际使用过程中个人电脑的配置可能不够。这个时候如果服务器配置够的话&#xff0c;可以尝试在服务器上装一下。但是服务器一般都是linux系统的&#xff0c;于是这篇教程就出现了… 可行性分析 通读安装…