Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【Linux】动静态库

【Linux】动静态库

作者头像
lovevivi
发布于 2023-05-10 00:36:58
发布于 2023-05-10 00:36:58
2.5K00
代码可运行
举报
文章被收录于专栏:萌新的日常萌新的日常
运行总次数:0
代码可运行

@TOC

动静态库

1. 设计库

库分为 静态库(.a)和动态库(.so) 库的命名 以c++的库为例 输入 ls /lib64/libstdc++* 以lib开头要去除 库的真实名字为 stdc++


一般云服务器,默认只会存在动态库,不需要动态库,静态库需要单独安装

myadd.h 实现一个加法的声明

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#pragma once     
int myadd(int d1,int d2);    

myadd.c 实现一个加法的实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include"myadd.h"    
int myadd (int d1,int d2)    
{    
   return d1+d2;    
}    

mysub.h 实现一个减法的声明

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#pragma once     
int sub(int d1,int d2);     

mysub.c 实现一个减法的实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include"mysub.h"    
int mysub(int d1,int d2)    
{    
  return d1-d2;    
} 

main.c 实现对myadd和mysub的调用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<stdio.h>    
  #include"myadd.h"    
  #include"mysub.h"    
  int main()    
  {    
      
    int x=100;    
    int y=34;    
    printf("%d+%d=%d\n",x,y,myadd(x,y));    
E>  printf("%d-%d=%d\n",x,y,mysub(x,y));    
    return 0;    
  } 

使用main.c mysub.c myadd.c 生成一个可执行程序 mytest 输入 gcc -o mytest myadd.c mysub.c main.c 指令


出于安全和便捷性考虑,都不想把源代码给别人,所以要把源代码打包


创建mylib目录代表自己 , otherperson目录代表其他人


main.c应该是另一个人用的代码,所以把main.c移动到otherprson目录中 输入指令 mv main.c otherperson/


在链接之前把源代码编译成.o的二进制目标文件 把所对应的源文件 经过预处理 编译 汇编 形成 .o文件


分别通过myadd.c 与mysub.c形成 myadd.o 与 mysub.o


为了不想给别人交付源代码,把所有的.h文件拷贝到 otherperson里面 同时把 所有的.o文件 也拷贝到 otherperson里面

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[yzq@VM-8-8-centos lesson1]$ cp *.h otherperson
[yzq@VM-8-8-centos lesson1]$ cp *.o otherperson

在otherperson 目录中 将main.c形成一个main.o的文件

把add.o sub.o main.o 链接形成 mytest 可执行程序


此时在otherperson目录中 使用 mytest 可执行程序去执行 就可以了

但是把一大堆的头文件和目标文件都传给 otherperosn目录 调用有点太繁琐了

1. 静态库打包

只有一个.o的压缩包

tar - c :创建一个新的归档文件即压缩包 tar- r : 若.c文件修改了,则对一个或者多个.o文件做替换


当前目录下包含 mylib otherperson 目录 以及 .o和.c文件


代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[yzq@VM-8-8-centos lesson1]$  ar -rc libmymath.a *.o

将当前目录下的 所有.o目标文件打包 并命名为 libmymath.a


在otherperson目录中,删除之前所预留的所有.o与.h文件以及 myetst可执行程序 此时otherperosn目录中只剩下 main.c


重新在mylib目录中取.o与.a文件

此时otherperson目录中存在.h文件 与main.c 以及 .o目标文件的压缩包

报错1

输入 gcc - o myetst main.c 指令 会报错

有库后,将库引入项目,必须让编译器找到头文件和库文件 因为引入的库 属于第三方库,gcc并不能理解用的那个库,要让编译器认识这个库


加入 -l选项 要链接哪一个库

此时依旧会报错


加入-L.选项 对应的库在那个路径下


输入 gcc -o mytest main.c -L. -lmymath 指令 即可正常运行可执行程序


创建.o与.h的压缩包

在mylib目录下


创建include目录 与 lib目录 拷贝所有的.h文件放在include目录下 ,拷贝所有的.a文件放在lib目录下


所以未来是将这两个目录传给用户 tar - c :创建一个新的归档文件即压缩包 tar - z : 使用打包的同时可以进行压缩 tar - f : 给归档文件一个名字 建议把 f 放在最后 tar -czf + 文件名.tgz +文件名

将dir与include两个目录进行打包 生成 mymath.tgz


在otherperson目录下

将属于mylib目录下的压缩包 mymath.tgz 拷贝到 otherperson 目录下


tar -x 解开文件 tar -xzf 文件名.tgz

使用 tar xzf 进行解包


报错2

头文件找不到 因为头文件在inlcude 里,不在当前路径下


在include的路径下,寻找头文件 依旧报错了,但是头文件找到了


告诉编译器库在lib中 还是会报错 ,因为lib库并不属于c/c++的标准库 还需要告诉库的名字是什么


将独立的将库引入otherperson中 ,可以正常运行

第三方库的使用

第三方库的使用 1.需要的是指定的头文件和库文件 2.如果没有默认安装到系统的gcc/g++默认的搜索路径下,用户必须指明对应的选项,告知编辑器, 头文件在哪里,库文件在哪里,库文件具体是谁

将头文件和库拷贝对应的系统路径

在otherperson目录下


将当前include下的所有内容拷贝到系统对应的include路径下


查看系统路径中就存在 myadd.h 与mysub.h


将dir拷贝到库的搜索路径下


由于将include对应的文件传入系统路径中以及将dir对应的文件传入库的搜索路径下 , 此时otherperson目录下只存在 main.c 文件 刚刚拷贝过去的库,属于非C/C++标准的库,所以被认为是第三方库


告诉它需要链接mymath库,就可以正常运行了,而不需要告诉头文件

  • 将下载下来的库和头文件,拷贝到系统默认路径下,这个行为就叫做在Linux下安装库 对于任何软件而言,安装和卸载的本质是拷贝到系统特定的路径下
  • 如果要安装第三方的库,(第一方库是语言,第二方库是操作系统系统接口),要正常使用,即便已经全部安装到系统中,gcc/g++必须用 -l 来指明具体库的名称

2. 动态库打包

在mylib目录下 制作动态库也需要.o目标文件,再将目标文件打包


动态库打包不使用 ar,而是直接使用gcc 并且加上 fPIC的选项 P代表 position 位置 I代表 independent 忽略 C 代表 code

生成myadd.o与mysub.o的目标文件,并形成与位置无关码


shared选项 代表打包的是一个共享库/动态库

将myadd.o 与mysub.o打包 成动态库,并命名为 mymath


在mylib目录下 使用 mkdir 分别创建 目录 include 与lib


将所有的.h文件拷贝到 include 目录下 即 include中存在头文件 将所有的.so文件拷贝到 lib目录下 即 lib中存在 动态库


将include 与lib 打包,并命名为 mymath.tgz


将 mymanth.tgz 这个包 拷贝到 otherperson目录中


在otherperson目录下

此时的otherperson目录下存在 mymanth.tgz 与main.c


通过 xzf 解包,显示出 include (存放头文件)与 lib (存放动态库)

报错

显示找不到头文件


加入-I后,在include下寻找头文件,但依旧会报错 ,因为找不到库了


加入 -L 后在lib 中寻找库 ,并加入-lmymath ,链接库mymath


运行时报错

但是在运行生成的可执行程序mytest时,还是会报错

说明链接时,动态库并没有真正链接到可执行程序


在上面 gcc 时,已经告诉系统库在哪里,叫什么了,为什么还是找不到? 只是告诉了编译器,并不是操作系统 运行时,你的.so并没有在系统默认的路径下,所以操作系统依旧找不到

找到动态库的方法
方法1 ——环境变量(临时方案)

LD_LIBRARY_PATH LD代表链接 LIBRARY 代表库 PATH 代表路径


显示为库的路径


将当前库的路径添加到环境变量中


查询环境变量时,发现当前库的路径已经在环境变量中


再次查看第三方库时,mymath.so有对应的第三方库了


此时mytest可以正常执行了

但是环境变量只在本次登录有效,若退出再进入,则环境变量还是找不到

方法2 ——建立软链接

在系统默认的路径下,建立一个软链接指向库


此时软链接指向这个库


查看第三方库时,libmymath.so有自己的第三方库


软链接是一个文件,所以即便关闭xshell,再次打开也能正常运行mytest 可执行程序

方法3——配置文件方案

使用 ldd 找不到 libmymath对应的第三方库


在系统当中存在配置文件 ld代表链接库 so代表动态库 conf代表配置文件

创建一个配置文件,并命名为look


输入 ls /etc/ld.so.conf.d/ 指令

查看系统的配置文件,就发现多了一个look的配置文件


由于动态库存放在otherperosn目录下的lib中, 所以进入lib目录中,显示当前库的路径,将其复制


使用vim进入自己创建的配置文件中,并把 上述复制好的库的路径粘贴到里面


输入 ldd mytest 指令,发现还是找不到第三方库


查看自己的配置文件时,已经有了对应的库的路径 还需让其生效


输入 sudo ldconfig 指令

就会让系统加载新的配置文件


即可正常运行程序

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-05-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【Linux】基础IO --- 软硬链接、acm时间、动静态库制作、动静态链接、动静态库加载原理…
2. 软链接文件soft_file.link有自己独立的inode,可以被当作独立文件看待。 而硬链接文件没有自己独立的inode,无论改变myfile.txt什么内容,hard_file.link都会随着一起改变,所以建立硬链接,实际上根本没有创建新文件,因为没有给硬链接分配独立的inode。
举杯邀明月
2023/04/12
3.7K0
【Linux】基础IO --- 软硬链接、acm时间、动静态库制作、动静态链接、动静态库加载原理…
Linux之动态库和静态库
我们了解了动态库和静态库的相关概念,但是我们还是不理解库是个什么东西。 假设,我们做了一个小程序,只希望提供给用户小程序的功能,不希望暴露我们的源码。我们可以选择给用户提供我们的.o可重定位目标二进制文件(gcc -c 文件)与头文件。让用户使用我们提供的.o文件和.h文件进行链接即可。(在编译时,只需要把源文件编译成.o文件,再将其链接即可形成一个可执行程序,因此我们可以直接提供,o文件)。 文件add.c
摘星
2023/10/15
7970
Linux之动态库和静态库
动态库与静态库
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。
二肥是只大懒蓝猫
2023/03/30
2.4K0
动态库与静态库
深入浅出动静态库
  当你在Linux系统上编写和运行程序时,动态库和静态库是两个非常重要的概念。它们不仅影响着程序的编译和执行效率,还直接关系到程序的可移植性和灵活性
用户11029129
2024/06/04
1590
深入浅出动静态库
【Linux】静态库和动态库
系统层面上有.和…硬链接指向目录。假设我们是超级用户,允许给目录建立硬链接,给根目录建立硬链接,从根目录开始查找,当查找硬链接的时候就是根目录,这时候递归式查找,形成了环路查找,最后导致软件无法正常进行查找工作!所以不允许普通用户给目录建立硬链接。
平凡的人1
2023/10/15
5990
【Linux】静态库和动态库
【Linux】————动静态库
现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。共享库的好处是,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。
用户11036582
2024/10/23
1770
【Linux】————动静态库
【Linux】详解动静态库的制作和使用&&动静态库在系统中的配置步骤
 库其实就是所有的.o文件用特定的方式进行打包形成一个文件,各个.o文件包含了源代码中的机器语言指令。
用户10923276
2024/04/09
7540
【Linux】详解动静态库的制作和使用&&动静态库在系统中的配置步骤
【Linux系统IO】六、动静态库
​ 我们之前学 gcc 的时候也有接触过一点动静态库的知识,现在要把它单独拿出来讲,主要是因为我们后面肯定在自己开发的时候需要包装自己的库,此时就需要有动静态库的原理知识和使用知识!
利刃大大
2025/03/11
1120
【Linux系统IO】六、动静态库
【Linux】软硬连接与动静态库
硬连接不是一个独立的文件,因为它没有的独立的inode号,用的是目标文件的inode
用户11029103
2025/03/10
1100
【Linux】软硬连接与动静态库
【Linux】动静态库(超详细)
💢 由于CentOS 8系统2021年12月31日已停止维护服务,CentOS 7系统将于2024年06月30日停止维护服务。CentOS官方不再提供CentOS 9及后续版本,不再支持新的软件和补丁更新。CentOS用户现有业务随时面临宕机和安全风险,并无法确保及时恢复。
IsLand1314
2024/11/19
1310
【Linux】动静态库(超详细)
Linux基础IO【软硬链接与动静态库】
假设你下载了一款游戏,你是否会跑到游戏所在目录中双击 .exe 打开游戏?答案是不会,大多数人都会通过桌面的快捷方式直接打开文件,而这个快捷方式实际就是对 .exe 的 软链接 文件;当你在游戏中加载地图、道具等资源时,这些数据是存在 .exe 文件中的吗?答案是当然不是,这些资源文件都以 库 的方式与 .exe 位于同一目录中,通常为动态库,在 Windows 中后缀为 dll,那么这些神奇的辅助文件是如何产生的?本文将带你一起揭晓
北 海
2023/07/01
3660
Linux基础IO【软硬链接与动静态库】
【Linux】从零开始认识动静态库 - 静态库
今天我们来学习动静态库。我们之前有没有使用过库呢??? 当然了: strerror strstr strcpy memset...等函数都要有具体的实现,那这个具体的实现在哪里呢???就是在我们的库中!
叫我龙翔
2024/05/11
2410
【Linux】从零开始认识动静态库 - 静态库
【Linux】动静态库
hello,大家好,今天我们继续学习Linux中的动静态库,我们将从不同的角度来学习如何使用,并如何制作一个可供他人使用的动静态库文件,并试着探究一下动态库加载问题。那我们就开始学习吧!!
破晓的历程
2024/06/24
1900
【Linux】动静态库
Linux:理解动静态库
    所以为了学习如何创建静态库和动态库以及理解静态链接和动态链接的本质。我们得从以下两个角度来理解:
小陈在拼命
2024/11/12
2050
Linux:理解动静态库
Linux静态库与动态库加载
        关于库相比大家之前肯定使用过,比如C/C++里面的标准库,STL里面的各种库,我们在调用STL里的容器时都需要使用库,那么库到底是什么呢?
咬咬
2024/06/12
4430
Linux静态库与动态库加载
【Linux】静态库和动态库
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。
YoungMLet
2024/03/01
1.1K0
【Linux】静态库和动态库
详解动态库和静态库
在C、C++中我们使用过标准库,比如在使用strerror、vector、string等时,都只是调用了这些函数接口,这些都是需要具体的实现。
南桥
2024/06/03
2710
详解动态库和静态库
【Linux】掌握库的艺术:我的动静态库封装之旅
在计算机编程中,库(Library)是一个预先编写的代码集合,包含了可以被其他程序调用的函数、类、变量和资源。库的主要目的是为了简化编程过程,提供常用功能的实现,促进代码重用,从而减少开发时间和提高软件的可靠性。
Yui_
2024/11/19
1150
【Linux】掌握库的艺术:我的动静态库封装之旅
linux动态库和静态库的使用_静态库的使用
例如,用test1.c、test2.c、test3.c、test4.c以及main1.c形成可执行文件,我们需要先得到各个文件的目标文件test1.o、test2.o、test3.o、test4.o以及main1.o,然后再将这写目标文件链接起来,最终形成一个可执行程序。
全栈程序员站长
2022/11/11
4.9K0
【Linux】动静态库
静态库是一种在编译阶段将库文件的内容直接整合到目标程序中的库文件形式。使用静态库后,库的代码会成为可执行文件的一部分,运行时不需要依赖外部库。
用户11305458
2025/01/09
1650
【Linux】动静态库
相关推荐
【Linux】基础IO --- 软硬链接、acm时间、动静态库制作、动静态链接、动静态库加载原理…
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档