【CMake系列】05-静态库与动态库编译

在各种项目类型中,可能我们的项目就是一个 库 项目,向其他人提供 我们开发好的 库 (windows下的 dll /lib ; linux下的 .a / .so);有时候在一个项目中,我们对部分功能 打包成 库,方便在不同地方进行调用

静态库 和 动态库 对项目 实现了 不同程度的解耦,

  • 静态库,往往会 链接时 加载,代码会复制一起打包到 可执行程序中
  • 动态库 更多是 运行时 加载,加载到内存,供可执行程序调用

学会使用 cmake 构建 静态库 和 动态库,是我们这篇文章的主要内容

本专栏的实践代码全部放在 github 上,欢迎 star !!!

如有问题,欢迎留言、或加群【392784757】交流

涉及命令

add_library(<name> [<type>] [EXCLUDE_FROM_ALL] <sources>...)

其中 type 用来指定构建库的类型【本篇 只针对 shared static 展开】
type

  • shared
  • static

使用库

# 路径配置相关 有时候需要
include_directories()
link_directories()

target_link_libraries() # 关键代码 

代码部分

log/
|—|—|log.cpp
|—|—|log.h
|—|—|CMakeLists.txt
test_log/
|—|—|test_log.cpp
|—|—|CMakeLists.txt
CMakeLists.txt

log.h

// log.h
#ifndef LOG_H
#define LOG_H


class Log
{
public:
  Log();
};
#endif

log.cpp

#include "log.h"
#include <iostream>
using namespace std;

Log::Log()
{
  cout << "create Log" << endl;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.20)

project(log)

add_library(log STATIC log.cpp log.h)

test_log 下

test_log.cpp

#include <iostream>
#include "log.h"
using namespace std;

int main()
{
  Log log;
  cout << "test log" << endl;
  return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.20)

project(test_log)

include_directories("../log") # 头文件路径

# 指定库查找路径 windows 自动找 ../log/build/Debug ../log/build/Release
link_directories("../log/build")

add_executable(test_log test_log.cpp)

#指定加载的库
target_link_libraries(test_log log)

构建静态库

type 指定的是 static

cd log
cmake -B build -S .
cmake --build build

cd test_log
cmake -B build -S .
cmake --build build

具体的还可以指定 lib的输出路径

动态库构建

我们 在 log 同级目录下 创建 CMakeLists.txt 内容如下

cmake_minimum_required(VERSION 3.20)

project(log)

include_directories(log)

# 添加log库编译 项目自带预处理变量 log_EXPORTS
add_library(log SHARED log/log.cpp)

add_executable(test_log test_log/test_log.cpp log)


target_link_libraries(test_log log)

windows下构建动态库存在问题

如果我们把 STATIC 改为 SHARED ,然后构建,发现会报错

LINK : fatal error LNK1104: 无法打开文件“Debug\log.lib”

其实 也就是 找不到.lib 文件

log.h 修改

// log.h
#ifndef LOG_H
#define LOG_H

// __declspec(dllexport) 导出 log 到lib文件中

#ifndef _WIN32
#define CPP_API
#else
// 针对 windows 平台
// log 库文件调用 dllexport
// test_log 调用 dllimport
// 通过预定义宏 确定是谁在调用
#ifdef log_EXPORTS
#define CPP_API __declspec(dllexport) // 库项目调用
#else
#define CPP_API __declspec(dllimport) // 调用库项目 调用
#endif
#endif

class CPP_API Log
{
public:
  Log();
};
#endif

需要将 dll 中定义的 函数、类符号 等导出到lib 才能找到 【也就是 符号导出】

  • dll 二进制代码
  • lib 函数 符号 地址 【理解程度有限】

做法就是在 函数、类等 前面 添加 _declspec(dllexport),

关于 dllexport dllimport 的更详细解释,推荐这个
https://zhuanlan.zhihu.com/p/680966160

然后进行构建,成功!
在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

idea 常用插件推荐

文章目录 1、Lombok2、Convert YAML and Properties File3、Grep Console4、MyBatisX5、Free MyBatis Tool6、MyBatis Log EasyPlus &#xff08;SQL拼接&#xff09;7、MyBatisPlus8、Eclipse theme9、Eclipse Plus Theme10、Rainbow Brackets Lite - Free and OpenSource&…

MongoDB CRUD操作:地理位置应用——通过地理空间查询查找餐厅

MongoDB CRUD操作&#xff1a;地理位置应用——通过地理空间查询查找餐厅 文章目录 MongoDB CRUD操作&#xff1a;地理位置应用——通过地理空间查询查找餐厅地图的扭曲搜索餐厅浏览数据查找当前邻居查找附近所有餐厅查找一定距离内的餐厅使用$geoWithin&#xff0c;不排序使用…

上位机图像处理和嵌入式模块部署(f407 mcu中tf卡模拟u盘)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 在f407开发板上面&#xff0c;本身是有一个usb接口的。这个usb接口也不仅仅是作为电源使用的&#xff0c;它还可以用来做很多的事情。一方面&#…

学Python,看一篇就够

学Python&#xff0c;看一篇就够 python基础注释变量标识符命名规则使用变量认识bugDebug工具打断点 数据类型输出转义字符输入输入语法输入的特点 转换数据类型pycharm交互运算符的分类赋值运算符复合赋值运算符比较运算符逻辑运算符拓展 条件语句单分支语法多分支语法拓展 if…

React中实现大模型的打字机效果

React 想实现一个打字机的效果&#xff0c;类似千问、Kimi 返回的效果。调用大模型时&#xff0c;模型的回答通常是流式输出的&#xff0c;如果等到模型所有的回答全部完成之后再展示给最终用户&#xff0c;交互效果不好&#xff0c;因为模型计算推理时间比较长。本文将采用原生…

Java1.8全套家政上门服务+springboot+ mysql +Thymeleaf 技术架构开发,家政APP系统在线派单,师傅入驻全套商业源码

Java1.8全套家政上门服务springboot mysql Thymeleaf 技术架构开发&#xff0c;家政APP系统在线派单&#xff0c;师傅入驻全套商业源码 家政预约上门小程序的实用性&#xff1f; 家政预约上门小程序的实用性主要体现在以下几个方面&#xff1a; 一、方便快捷的预约体验&#…

运行编译openjdk12-33

编译环境 ubuntu20 Ubuntu里用户可以自行选择安装GCC或CLang来进行编译&#xff0c;但必须确保最低的版本为GCC 4.8或者CLang 3.2以上&#xff0c;官方推荐使用GCC 7.8或者CLang 9.1来完成编译。 源码 https://github.com/openjdk/jdk/tree/jdk-12%2B33 安装gcc sudo apt…

气膜羽毛球馆如何提升运动体验—轻空间

随着人们对健康和运动的关注度日益增加&#xff0c;羽毛球作为一项受欢迎的运动&#xff0c;得到了越来越多人的喜爱。而气膜羽毛球馆&#xff0c;以其独特的优势&#xff0c;正在改变传统羽毛球馆的运动体验。那么&#xff0c;气膜羽毛球馆是如何提升运动体验的呢&#xff1f;…

白酒:全球化背景下产地白酒的国际竞争与合作

在全球化背景下&#xff0c;云仓酒庄豪迈白酒作为中国白酒的品牌之一&#xff0c;面临着国际竞争与合作的机遇与挑战。国际市场竞争的激烈以及消费者需求的多样化&#xff0c;要求云仓酒庄豪迈白酒不断提升品质、拓展市场以及加强国际合作&#xff0c;以提升品牌竞争力和市场份…

深度学习Day-19:DenseNet算法实战与解析

&#x1f368; 本文为&#xff1a;[&#x1f517;365天深度学习训练营] 中的学习记录博客 &#x1f356; 原作者&#xff1a;[K同学啊 | 接辅导、项目定制] 要求&#xff1a; 根据 Pytorch 代码&#xff0c;编写出 TensorFlow 代码研究 DenseNet 与 ResNetV 的区别改进思路是…

SBOM是如何帮助医疗器械制造商提高产品透明度的?

SBOM&#xff08;软件物料清单&#xff09;通过以下方式帮助医疗器械制造商提高产品透明度&#xff1a; 1. 详细记录软件组成 SBOM详细列出了医疗器械所使用的所有软件组件、版本、作者、许可证信息等。这使得制造商能够清晰地了解产品的软件组成&#xff0c;包括每个组件的来…

Plotly的魔力:如何用Python创建令人惊叹的图表?

大家好&#xff0c;在数据分析和可视化领域&#xff0c;图表是不可或缺的工具。它们可以帮助我们更直观地理解数据趋势和模式。今天&#xff0c;我们要介绍的是一个强大的Python库——Plotly&#xff0c;它可以让你轻松创建交互式、漂亮的图表。无论你是数据科学家、分析师&…

C++学习/复习12--vector的实现(三个基本成员函数/迭代器/扩容/插入删除/重载/测试/杨辉三角)

一、构造函数 1.匿名对象与构造函数 在C中&#xff0c;匿名对象是一个临时对象&#xff0c;它没有名称&#xff0c;通常在对象创建后&#xff0c;只使用一次后就被销毁。创建匿名对象的方式是在创建对象时不使用变量名。 下面是创建匿名对象的几种方式&#xff1a; 直接使用…

【Linux】(二)—— 用户和用户组管理

在了解了Linux基础命令格式后&#xff0c;今天我要介绍的是Linux的用户管理 目录 root用户用户管理操作用户ID切换用户查看用户添加用户指定密码修改用户信息删除用户退出登录查看登陆系统的用户 用户组的管理增加新用户组查看用户组删除用户组修改用户组切换用户组 与用户有关…

GAMES101笔记

Games101 文章目录 Games101一、Review of Linear Algebra 线性代数向量向量点乘&#xff1a;判断同向反向、接近程度点乘基本属性点乘坐标系运算向量投影向量叉乘&#xff1a;判定左右、判定内外叉乘基本属性&#xff08;右手坐标系&#xff09;&#xff1a;不满足交换律叉乘坐…

CSS函数:fit-content与matrix的使用

网格函数 fit-content()属于网格函数&#xff0c;除此之外的网格函数还有&#xff1a;CSS函数&#xff1a; 实现数据限阈的数字函数。顾名思义&#xff0c;这三个函数只能在网格布局中使用。fit-content()函数主要是用于给定布局可用大小&#xff0c;适应内容&#xff0c;其功…

【数据结构】排序(直接插入、折半插入、希尔排序、快排、冒泡、选择、堆排序、归并排序、基数排序)

目录 排序一、插入排序1.直接插入排序2.折半插入排序3.希尔排序 二、交换排序1.快速排序2.冒泡排序 三、选择排序1. 简单选择排序2. 堆排序3. 树排序 四、归并排序(2-路归并排序)五、基数排序1. 桶排序&#xff08;适合元素关键字值集合并不大&#xff09;2. 基数排序基数排序的…

十六、【源码】plugins插件

源码地址&#xff1a;https://github.com/mybatis/mybatis-3/ 仓库地址&#xff1a;https://gitcode.net/qq_42665745/mybatis/-/tree/16-plugin plugins插件 plugins功能分为两部分 1.首先是在xml解析时解析出配置的插件类&#xff0c;并实例化放入拦截器链中 2.其次执行…

量化投资分析平台 迅投 QMT(四)获取标的期权的代码

量化投资分析平台 迅投 QMT [迅投 QMT](https://www.xuntou.net/?user_code7NYs7O)我目前在使用有了底层标的如何获取期权的交易代码呢&#xff1f;上代码历史帖子 迅投 QMT 我目前在使用 两个月前&#xff08;2024年4月&#xff09;迅投和CQF有一个互动的活动&#xff0c;进…

Java实现2048游戏源代码(启动即可玩)

使用Java语言从零到一开发经典2048游戏的全部源代码及详尽的开发教程。 适合Java初学者、游戏开发爱好者以及想要深入理解Swing GUI框架的开发者学习与参考。 知识领域&#xff1a;游戏开发、Java编程、图形用户界面(GUI)设计 技术关键词&#xff1a;Java Swing、事件监听、多…