【linux深入剖析】动态库的使用(续) | 动静态库的链接


🍁你好,我是 RO-BERRY
📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识
🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油

在这里插入图片描述


目录

  • 回顾
  • 1. 打包库的使用
  • 2. 动态库可执行程序无法运行的问题
  • 3. 动态库可执行程序运行解决方法
    • 3.1 将库安装到系统中(/lib64/)
    • 3.2 环境变量LD_LIBRARY_PATH
    • 3.3 对库文件建立软链接
    • 3.4 ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新
  • 4. 动静态库的链接


回顾

  • 回顾上节,我们在创建了动态库libmymath.so

在这里插入图片描述

  • 我们使用指令

gcc main.c -L. -lmymath
-L .(-L + 路径表示myc这个库在哪个路径下,这里就是用的点来代表当前路径,)
-lmymath(指明要链接mymath这个动态库)
因为gcc默认是调用的是C语言标准库,所以我们要在这里指明要使用我们的库

在这里插入图片描述

编译生成了文件a.out,运行程序是可以运行的

在这里插入图片描述

  • 使用ldd查看文件是否是调用的我们所创建的库

在这里插入图片描述

其实际链接的是/lib64/libc.so.6,这就是C语言标准库,同时也依赖了我们自己的库,libmymath.so

结论:编写库的人:未来要给别人(用这个库的人),交付的是:头文件+库文件。


我们想让别人使用我们的库就需要我们对其进行发布
将我们的库发布出来就是Makefile中output部分

  1 libmymath.so:add.o sub.o
  2     gcc -shared -o $@ $^
  3 .o:.c
  4     gcc -shared -c $<
  5 #add.o:add.c
  6 #   gcc -c -fPIC $< -o $@
  7 #sub.o:sub.c
  8 #   gcc -c -fPIC $< -o $@
  9 .PHONY:clean
 10 clean:
 11   rm -f *.o libmymath.so
 12 
 13 .PHONY:output                                                                                                                                                                           
 14 output:
 15 	mkdir -p ./mylib/mylib/
 15 	mkdir -p ./mylib/Headfile/
 15	 	cp -rf libmymath.so ./mylib/mylib/
 15	 	cp -rf add.h sub.h ./mylib/Headfile/
 15	 	tar -czf mylib.tgz mylib

output的工作就是帮我们在user目录下创建一个mylib的文件以及将我们的库拷贝过去,并且帮我们在user目录下创建一个Headfile的文件以及将我们的头文件拷贝过去,最后一步是打包文件

在这里插入图片描述

这里的mylib.tgz就是我们的库打包文件

  • 我们新建一个目录然后将打包文件移动到此目录下,实行解压,解压之后删除压缩包

在这里插入图片描述

这样我们要使用这个库就可以轻松使用了


1. 打包库的使用

接下来我们对其进行使用

  1. 我们将main.c主文件移动到该路径下进行编译

在这里插入图片描述

编译是无法运行的,这里缺少了头文件

  1. 我们使用指令gcc -o mytest main.c -I ./mylib/Headfile

-I + 路径是让编译器查找头文件时不仅在当前路径以及库路径查找也要在这个路径下进行查找
这样依然会报错,这是因为没有用到我们的库

  1. 我们使用指令gcc -o mytest main.c -I ./mylib/Headfile/ -L ./mylib/lib -lmymath链接到我们自己的库

在这里插入图片描述

运行出来了,就可以看到我们的mytest文件


我们上面这一长串也还是太长了,我们要想只链接一下我们的库就能编译怎么操作?

gcc -o mytest main.c -lmymath


解决办法:

  • 方法一:我们将库安装到系统的默认路径

所谓的把库(其他软件)安装到系统中,本质就是把对应的文件拷贝到系统指定的路径中

  1. 首先我们的系统默认头文件路径一般都在系统的include路径下

在这里插入图片描述

  1. 我们想拷贝到这个路径下需要我们提升权限,这些系统路径一般都是机器规定好的,都是root权限

在这里插入图片描述

  1. 系统默认的库路径在我们的lib64目录下

在这里插入图片描述
4. 拷贝库文件到默认库里

在这里插入图片描述

  1. 测试

在这里插入图片描述

但是在这里我们是不推荐将我们写的不成熟的库与头文件写入系统里的,所以这种方法是不推荐的


2. 动态库可执行程序无法运行的问题

我们如果不将库文件以及头文件移动到系统里,我们就还是只能采取我们的老办法,但是为什么我们生成的文件无法运行呢?
在这里插入图片描述

这里的报错说明了我们找不到这个目录


静态库在编译的时候是不会出现这个问题的,静态库的本质是从库里面把它的代码拷贝到这个程序当中,所以对静态库来讲,只要形成了可执行程序,静态库在后续就不需要再被使用了,所以在我们后续使用的时候就不会再出现查找静态库的任何动作

反而对动态库来讲,我们编译的时候是我们自己给它指明了我们的库路径,所以它编译成功了,但是形成文件之后,它再次找不到库了,这也就是动态库与静态库的差别

对于动态库:这里有两套路径

编译时的库搜索路径是给gcc的
运行时的库搜索路径是给OS的

也就是说我们在程序运行的时候也需要给它库的路径


回归正题,我们使用指令ldd来查看一下可执行文件的库路径
在这里插入图片描述
可以很清楚的看到,我们自己的库处于找不到的境地


3. 动态库可执行程序运行解决方法

我们有四种方法去解决这个问题

3.1 将库安装到系统中(/lib64/)

在这里插入图片描述

可以看到拷贝过去之后,我们的可执行文件的库再也没有出现not found,并且程序已经可以运行


3.2 环境变量LD_LIBRARY_PATH

环境变量LD_LIBRARY_PATH :系统运行程序时,动态库查找的辅助路径

在这里插入图片描述
系统默认在/lib64/路径下找,但是程序运行时不仅仅在/lib64/下找,也会在这个辅助路径下进行寻找,以冒号为分隔符,在目录下寻找

  • 我们将库的目录添加到环境变量LD_LIBRARY_PATH 里即可
    在这里插入图片描述

但是环境变量有一个缺点,那就是我们重启xshell之后,这个环境变量是会回到初始状态的


3.3 对库文件建立软链接

使用如下指令,我们在库文件里添加同名库文件软链接

sudo ln -s /home/cmj/work/newfile/mylib/mylib/libmymath.so /lib64/libmymath.so

在这里插入图片描述

我们再来运行,即可运行

在这里插入图片描述

3.4 ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新

删除软链接,文件变为not fount状态
在这里插入图片描述

我们先来认识一下/etc/系统配置文件路径

在这里插入图片描述

这里面有一个/etc/ld.so.conf.d/
名称含义 ld是链接,so就是动态库,conf就是配置文件,.d就是指它是个目录

它是允许我们去配置各种各样的文件的,我们创建一个我们自己的配置文件cmj.conf,里面没有写任何东西
在这里插入图片描述

这个配置文件只需要我们写入我们需要其去识别的库路径就可以了
配置后需要我们更新环境变量的配置系统,用到指令 ldconfig

在这里插入图片描述
文件就重新成功运行了


4. 动静态库的链接

我们先实现动静态库全创建并帮我们打包的Makefile

  1 libmymath.a:add.o sub.o
  2     ar -rc $@ $^
  3     rm *.o
  4 %.o:%.c
  5     gcc -c $<
  6   
  7 libmymath.so:add.o sub.o
  8     gcc -shared -o $@ $^
  9 %.o:%.c             
 10     gcc  -c -fPIC $<
 11 #add.o:add.c        
 12 #   gcc -c -fPIC $< 
 13 #sub.o:sub.c
 14 #   gcc -c -fPIC $<                             
 15 .PHONY:clean
 16 clean:       
 17   rm -f -rf *.o libmymath.so *.a mylib mylib.tgz
 18                                                                                                                                                                                         
 19 .PHONY:output                     
 20 output:                           
 21         mkdir -p ./mylib/mylib/  
 22         mkdir -p ./mylib/Headfile/  
 23         cp -rf *.so ./mylib/mylib/
 24         cp -rf *.a ./mylib/mylib/
 25         cp -rf *.h ./mylib/Headfile/
 26         tar -czf mylib.tgz mylib
  • 依次输入指令

make
make libmymath.so
make output

在这里插入图片描述

  • 再将我们打包的压缩包文件传入user,user是我们假装的外部用户

在这里插入图片描述
我提供的既有静态库又有动态库。
我们将文件进行编译
输入指令

gcc -o mytest main.c -I ./mylib/Headfile/ -L ./mylib/mylib/ -lmymath

我们在最后并没有指明其使用动态库还是静态库,我们使用的是库的名字
在这里插入图片描述

最后我们可以看到我们动态库和静态库同时提供的时候,gcc默认使用的是动态库!!!

我们也可以指定使用静态库,在当初的库名后面加上-static即可
在这里插入图片描述


  • 我们将库里的动态库移到上级目录,再次运行该程序

在这里插入图片描述
我们可以发现它不依赖我们自己写的静态库

如果我们只提供的静态库,那我们的可执行程序也没办法,只能对该库进行静态链接,但是程序不一定整体式静态链接的


  • 我们将动态库移动回来,将静态库移除

在这里插入图片描述

我们尝试加-static

在这里插入图片描述如果我们只提供动态库,默认只能动态链接,非得静态链接,会发生链接标错


结论:

  1. 如果我们同时提供动态库和静态库,gcc默认使用的是动态库
  2. 如果我们非要使用静态链接,我们必须使用的是动态库
  3. 如果我们只提供的静态库,那我们的可执行程序也没办法,只能对该库进行静态链接,但是程序不一定整体式静态链接的
  4. 如果我们只提供动态库,默认只能动态链接,非得静态链接,会发生链接标错

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

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

相关文章

JavaWeb--JavaScript-事件绑定/BOM/DOM编程

目录 1. 事件绑定 1.1. 什么是事件 1.2. 常见事件 1.3. 事件的绑定 1.3.1. 属性绑定 1.3.2. DOM编程绑定 1.4. 事件的触发 1.4.1. 行为触发 1.4.2. DOM编程触发 2. BOM 编程 2.1. 什么是 BOM 2.2. window对象的常见属性(了解) 2.3. window对象的常见方法(了解) 2…

如何准备2024年汉字小达人:18道历年考题示例和解析、备考提醒

现在距离2024年第11届汉字小达人比赛还有六个多月的时间&#xff0c;如何利用这段时间有条不紊地备考呢&#xff1f;我的建议是两手准备&#xff1a;①把小学1-5年级的语文课本上的知识点熟悉&#xff0c;重点是字、词、成语、古诗。阅读理解不需要。②把历年真题刷刷熟&#x…

nacos服务器挂了之后springboot/springcloud服务会挂吗?不会挂(顺便深入源码分析nacos配置中心客户端核心功能实现)

文章目录 nacos挂了之后服务会挂吗&#xff1f;不会挂&#xff08;深入源码分析&#xff09;展开nacos客户端源码找本地缓存配置相关文件客户端内存缓存客户端健康状态获取配置的实现 nacos挂了之后服务会挂吗&#xff1f;不会挂&#xff08;深入源码分析&#xff09; 展开nac…

适用于数据找回恢复的 12 个免费数据恢复工具

技术使我们的生活一天比一天轻松&#xff0c;我们已经越来越习惯于使用电脑、智能手机、桌子等设备&#xff0c;我们喜欢使用手机、电脑和其他数字设备&#xff0c;并将我们宝贵的数据存储在它们上面。当然&#xff0c;我们不能忍受丢失数据&#xff0c;因为这些设备都不可靠。…

C语言如何生成随机数以及设置随机数的范围

一、随机数的生成 1.rand()函数 C语言提供了⼀个函数叫 rand&#xff0c;这函数是可以生成随机数的&#xff0c;函数原型如下所示&#xff1a; int rand (void); rand函数会返回⼀个伪随机数&#xff0c;这个随机数的范围是在0~RAND_MAX之间&#xff0c;这个RAND_MAX的大小是依…

【项目实战】记录一次PG数据库迁移至GaussDB测试(上)

目录 一、说明 1.1、参考文档 1.2、注意事项 1.3、环境基本情况 二、GaussDB新环境安装 2.1 配置操作环境变量 2.1.1 关闭防火墙 步骤1 执行以下命令&#xff0c;检查防火墙是否关闭。 步骤2 执行以下命令&#xff0c;关闭防火墙并禁止开机启动。 步骤3 修改/etc/sel…

【Java-TesseractOCR】通过Java实现OCR

通过Java实现OCR 一、TesseractOCR二、引入pom训练集下载地址三、引入训练集三、使用 一、TesseractOCR 本文使用的是TesseractOCR进行识别 二、引入pom <dependency><groupId>net.sourceforge.tess4j</groupId><artifactId>tess4j</artifactId&…

【网站项目】数学辅导微信小程序

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

python数据可视化——笔记1

1、pyecharts模块 Pyecharts 是一个 Python 可视化库&#xff0c;绘制多种类型的图表&#xff0c;创建交互式和美观图表。 官方网站:https://pyecharts.org/#/zh-cn/ pyecharts画廊&#xff1a; https://gallery.pyecharts.org/#/README 安装pyechart包&#xff0c;在pych…

每日一题(leetcode209):长度最小的子数组--前缀和+二分法

得到前缀和数组之后&#xff0c;进行一次遍历&#xff0c;每遍历一个值&#xff0c;在它的后半部分利用二分法&#xff08;所有数据都为正&#xff0c;前缀和数组有序递增&#xff09;寻找第一个大于可以使区间和大于等于target的值&#xff08;也可能找不到&#xff09;&#…

jenkins+gitlab配置

汉化 1、安装Localization: Chinese (Simplified)插件 &#xff08;此处我已安装&#xff09; &#xff08;安装完成后重启jenkins服务即可实现汉化&#xff09; 新增用户权限配置 1、安装插件 Role-based Authorization Strategy 2、全局安全配置 3、配置角色权限 4、新建…

vue3+ts中判断输入的值是不是经纬度格式

vue3ts中判断输入的值是不是经纬度格式 vue代码&#xff1a; <template #bdjhwz"{ record }"><a-row :gutter"8" v-show"!record.editable"><a-col :span"12"><a-input placeholder"经度" v-model:v…

优化调度排班管理:数字化架构下的创新实践

引言&#xff1a;调度排班管理在医院运营中具有重要意义。传统的排班方式往往存在效率低下、资源浪费等问题&#xff0c;为了提高医院运营效率和人力资源利用率&#xff0c;数字化架构下的调度排班管理成为了一种创新实践。 1. 数字化架构的基础构建 在数字化架构下&#xff…

EasyExcel追加写入数据,分批查询多次写入场景下,注意使用方式【OOM警告】

使用.withTemplate(file) 将临时数据文件和真实数据文件合并的方式&#xff0c;在生产环境大批量数据下&#xff0c;完全不可取&#xff0c;有很高的内存溢出风险 伪代码 public static void writeAppend(String fileName) {String filePath "tempDir".concat(Fil…

c++24.4.13-const修饰指针

1、const修饰指针-常量指针 2、const修饰常量-指针常量 3、const既修饰指针又修饰常量 示例

Laravel 11入门:使用ServBay打造高效开发环境

Laravel 11发布&#xff0c;改进了不少功能。 它引入了更加流畅的应用结构、每秒限速、健康路由等特性。 此外&#xff0c;Laravel还推出了第一方可扩展的WebSocket服务器Laravel Reverb&#xff0c;为你的应用提供强大的实时功能。 在今天的指南中&#xff0c;我将设置一个…

MATLAB Simulink仿真搭建及代码生成技术—01自定义新建模型模板

MATLAB Simulink仿真搭建及代码生成技术 目录 01-自定义新建模型模板点击运行&#xff1a;显示效果&#xff1a;查看模型设置&#xff1a; 01-自定义新建模型模板 新建模型代码如下&#xff1a; function new_model(modelname) %建立一个名为SmartAss的新的模型并打开 open_…

Golang | Leetcode Golang题解之第26题删除有序数组中的重复项

题目&#xff1a; 题解&#xff1a; func removeDuplicates(nums []int) int {n : len(nums)if n 0 {return 0}slow : 1for fast : 1; fast < n; fast {if nums[fast] ! nums[fast-1] {nums[slow] nums[fast]slow}}return slow }

Ubuntu22.04 + ROS2 Humble的环境配置

Ubuntu22.04 ROS2 Humble的环境配置 文章目录 Ubuntu22.04 ROS2 Humble的环境配置(1) Set locale(2) Setup Sources(3)安装ROS2(4)检查是否成功安装 参考官方网站ROS2-Installation ROS2的各种版本及维护计划&#xff0c;可以参考ROS2-List of Distributions (1) Set locale…

2024年认证杯SPSSPRO杯数学建模D题(第一阶段)AI绘画带来的挑战全过程文档及程序

2024年认证杯SPSSPRO杯数学建模 D题 AI绘画带来的挑战 原题再现&#xff1a; 2023 年开年&#xff0c;ChatGPT 作为一款聊天型 AI 工具&#xff0c;成为了超越疫情的热门词条&#xff1b;而在 AI 的另一个分支——绘图领域&#xff0c;一款名为 Midjourney&#xff08;MJ&…