【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.o2     gcc -shared -o $@ $^3 .o:.c4     gcc -shared -c $<5 #add.o:add.c6 #   gcc -c -fPIC $< -o $@7 #sub.o:sub.c8 #   gcc -c -fPIC $< -o $@9 .PHONY:clean10 clean:11   rm -f *.o libmymath.so12 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.o2     ar -rc $@ $^3     rm *.o4 %.o:%.c5     gcc -c $<6   7 libmymath.so:add.o sub.o8     gcc -shared -o $@ $^9 %.o:%.c             10     gcc  -c -fPIC $<11 #add.o:add.c        12 #   gcc -c -fPIC $< 13 #sub.o:sub.c14 #   gcc -c -fPIC $<                             15 .PHONY:clean16 clean:       17   rm -f -rf *.o libmymath.so *.a mylib mylib.tgz18                                                                                                                                                                                         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. 如果我们只提供动态库,默认只能动态链接,非得静态链接,会发生链接标错

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis-缓存穿透与雪崩

一&#xff0c;缓存穿透&#xff08;查不到&#xff09; 在默认情况下&#xff0c;用户请求数据时&#xff0c;会先在缓存(Redis)中查找&#xff0c;若没找到即缓存未命中&#xff0c;再在数据库中进行查找&#xff0c;数量少可能问题不大&#xff0c;可是一旦大量的请求数据&a…

IDM激活步骤-亲测可用

前言&#xff1a;我试了3种方法&#xff0c;仅以下方法激活成功&#xff0c;其他都是30天试用 使用步骤&#xff1a; 1.从官网下载IDM并安装&#xff1a;https://www.internetdownloadmanager.com/ 2.下载激活工具&#xff1a;https://wwif.lanzouw.com/iSY2N16s81xi &#…

【NLP练习】调用Gensim库训练Word2Vec模型

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、准备工作 1.安装Gensim库 使用pip安装&#xff1a; !pip install gensim2. 对原始语料分词 选择《人民的民义》的小说原文作为语料&#xff0c;先采用…

Composer安装与配置

Composer&#xff0c;作为PHP的依赖管理工具&#xff0c;极大地简化了PHP项目中第三方库的安装、更新与管理过程。本文将详细介绍Composer的安装步骤、基本配置方法&#xff0c;以及一些实用的操作示例&#xff0c;帮助读者快速上手并熟练运用Composer。 一、Composer安装 环…

性能优化-02

uptime 依次显示当前时间、系统运行时间以及正在登录用户数&#xff0c;最后三个数字依次则是过去1分钟、5 分钟、15 分钟的平均负载(Load Average) 平均负载是指单位时间内&#xff0c;系统处于可运行状态和不可中断状态的平均进程数&#xff0c;也就是平均活跃进程数&#xf…

R语言绘图:绘制横向柱状图

代码主要实现&#xff1a; 对数据进行排序&#xff0c;并且相同分组的数据会有相同的颜色。最后&#xff0c;绘制横向柱状图。 # 加载ggplot2包 library(ggplot2)# 示例数据&#xff0c;假设有三列&#xff1a;Group, Variable, Value data <- data.frame(Group factor(c(…

探索HTTP协议的世界 | 从基础到高级应用,原理与实践相结合(请求篇)

从基础到高级应用&#xff0c;原理与实践相结合 什么是Http历代Http协议主要特点格式和URL协议内容请求行格式如下请求方法简单案例 消息报头报头域的格式HTTP消息报头类型普通报头优化方向报头&#xff08;缓存&#xff09;Cache-Control的选项其他相关的缓存报头 请求报头Acc…

无惧烈日!看小米SU7的防晒杀手锏

小米SU7&#xff0c;为颜值设计&#xff0c;更为体验设计。 其中&#xff0c;女性车主占比近30%&#xff0c;算上给太太/女朋友、姐姐、妹妹等亲友买的&#xff0c;实际女车主预计占比是40%甚至50%。 为啥呢&#xff1f;因为小米SU7好看、防晒、收纳&#xff0c;丰富优雅。 小米…

git工具上传文件超过100MB解决方法

Github 上传超过100M的大文件 - 简书 (jianshu.com) 看到一个不错的贴子。 29660DESKTOP-CAB6SQB MINGW64 /d/predict-system $ git init Initialized empty Git repository in D:/predict-system/.git/29660DESKTOP-CAB6SQB MINGW64 /d/predict-system (master) $ git lfs tr…

基于java+springboot+vue实现的居家养老健康管理系统(文末源码+Lw)23-313

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装智慧社区居家养老健康管理系统软件来发挥其高效地信息处理…

ubuntu下man手册 查不到 pthread_mutex_lock等系列函数用法的问题

问题 在ubuntu系统中无法man到 pthread_mutex_lock pthread_mutex_trylock pthread_mutex_unlock等函数 $ man pthread_mutex_lock 没有 pthread_mutex_lock 的手册页条目解决方式 输入以下命令 sudo apt-get install manpages-posix manpages-posix-dev 然后输入密码 再次m…

主从同步优化

2.3.主从同步优化 主从同步可以保证主从数据的一致性&#xff0c;非常重要。 可以从以下几个方面来优化Redis主从就集群&#xff1a; 在master中配置repl-diskless-sync yes启用无磁盘复制&#xff0c;避免全量同步时的磁盘IO。Redis单节点上的内存占用不要太大&#xff0c;…

SQLite 在Android安装与定制方案(十七)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLite超详细的编译时选项&#xff08;十六&#xff09; 下一篇&#xff1a;SQLite Android 绑定&#xff08;十八&#xff09; 安装 有三种方法可以将 SQLite Android 绑定添加到应用程序&#xff1a; 1、通过…

计算机网络----第十天

配置vlan 广播风暴的含义&#xff1a; 含义&#xff1a;设备发出的广播帧在广播域中传播&#xff0c;占用网络带宽&#xff0c;降低设备性能 隔离广播的方式&#xff1a; 方式&#xff1a;用路由器来隔离广播 用VLN隔离广播 vlan的定义&#xff1a; 定义&#xff1a;虚拟…

单调栈用法

文章目录 1. 单调栈1.1 理解单调栈&#xff08;模板&#xff09;1.2 每日温度1.3 子数组的最小值之和1.4 柱状图中最大的矩形1.5 最大矩形1.6 最大宽度坡1.7 去除重复字母 1. 单调栈 单调栈经典的用法&#xff1a; 对每个位置都求&#xff1a; 当前位置的左侧比当前位置的数…

openGauss_5.1.0 企业版快速安装及数据库连接:单节点容器化安装

目录 &#x1f4da;第一章 官网信息&#x1f4da;第二章 安装&#x1f4d7;下载源码&#x1f4d7;下载安装包&#x1f4d7;修改版本&#x1f4d7;解压安装包&#x1f4d7;运行buildDockerImage.sh脚本&#x1f4d7;docker操作&#x1f4d5;查看docker镜像&#x1f4d5;启动dock…

013_NaN_in_Matlab中的非数与调试方法

Matlab中的非数与调试方法 是什么&#xff1f; Matlab编程&#xff08;计算器使用&#xff09;中经常有个错误给你&#xff0c;这句话里可能包含一个关键词NaN。大部分学生都有过被 NaN 支配的痛苦记忆。 NaN 是 Not a Number 的缩写&#xff0c;表示不是一个数字。在 Matla…

负荷预测 | Matlab基于TCN-GRU-Attention单输入单输出时间序列多步预测

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab基于TCN-GRU-Attention单输入单输出时间序列多步预测&#xff1b; 2.单变量时间序列数据集&#xff0c;采用前12个时刻预测未来96个时刻的数据&#xff1b; 3.excel数据方便替换&#xff0c;运行环境matlab20…

R: 支持向量机(Support Vector Machine,简称SVM)

在数据科学和机器学习领域中&#xff0c;支持向量机&#xff08;Support Vector Machine&#xff0c;简称SVM&#xff09;是一种强大的监督学习算法&#xff0c;常用于分类和回归分析。它的优点之一是可以适用于复杂的数据集&#xff0c;并且在高维空间中表现良好。在本文中&am…

MindOpt APL向量化建模语法的介绍与应用(2)

前言 在数据科学、工程优化和其他科学计算领域中&#xff0c;向量和矩阵的运算是核心组成部分。MAPL作为一种数学规划语言&#xff0c;为这些领域的专业人员提供了强大的工具&#xff0c;通过向量式和矩阵式变量声明以及丰富的内置数学运算支持&#xff0c;大大简化了数学建模…