当前位置: 首页 > news >正文

Linux: 静态库和动态库

目录

一 前言

二 什么是库

 三 静态库和静态链接

1. 生成静态库

 2. 生成动态库


一 前言

在Linux环境下,我们使用gcc编译链接代码时,可以分为静态链接动态链接

  • 静态链接即在编译链接时,将代码所使用到的静态库文件代码全部拷贝到可执行文件中(拷贝实质上是将库文件的代码展开拷贝至我们的可执行程序的代码段。,这样做的缺点是可执行文件会生成的比较大,优点是此时再运行可执行文件就不需要再查找库了。静态库文件一般以 .a 结尾
  • 动态链接不会在编译时将动态库文件的代码加入到可执行文件中,而是在可执行文件运行时,去查找所需的动态库,并将其加载到相应的进程中,并且不同的进程可以共享这些动态库,动态库文件一般以 .so 结尾。

  • 库:简单来说就是由别人所写的一些函数、方法等代码经过归档整合之后发布出来以供大家使用的东西就称为库。每个人都可以生成库,然后发布出去以供别人使用。Linux库文件的命名通常以lib为前缀,后面跟库名称和文件扩展名。例如,一个名为math的静态库文件可能命名为libmath.a,而对应的动态库文件则可能命名为libmath.so


二 什么是库

 🚀:在这里我们创建了四个文件分别是my_sub.h my_sub.c my_add.h my_add.c

vim分屏操作:Esc +: vs 文件名

在可执行文件的编译过程,我们添加选项将编译和链接分开,先使用 -c 选项将代码编译成目标文件先不做链接 

🌞 我们知道目标文件my_add.o my_sub.o 就已经可以链接成可执行程序了,如果我们将上述my_add.o my_sub.o 拷贝到上级目录test中,那么在test目录中是不是就可以调用我们写的函数了.

为了演示,我们在test路径下创建一个main.c文件,来调用我们写的my_sub.c   my_add.c函数

 我们将lesson20中的my_add.o my_sub.o my_add.h my_sub.h 拷贝到test目录下,那样我们不就可以调用函数了吗

 

运行结果:

🚀:上述的演示demo:如果我们不想给对方我们的源代码,我们可以提供.o目标二进制文件, 来进行链接即可。

未来我们可以给对方提供.o(方法的实现)  .h(都有什么方法),这就是库的思想。

如果我们有大量的.o文件,那样别人想用我们的程序,是不是就要拷贝大量的.o文件,这样会造成大量的命令行,所以为了方便对方更好的使用,我们将.o文件整体打包,给对方提供一个库文件。

多个.o------->文件---->库-------->根据打包方式不同分为  :动态库,  静态库

库的本质就是.o文件的集合


 三 静态库和静态链接

1. 生成静态库

 清理库

有了库文件,我们该怎样让别人去用这个库文件呢 

我们直接拷贝这个库可以吗?答案是不行的

交付库----->库文件.a +匹配的头文件都给别人。   接下来我们重写改写makefile文件,把头文件也给别人。

🚴有了发布软件:mylib 我们如何给别人用呢? 

 

 🚵:编辑器器在搜索头文件的时候默认在当前目录或者系统指定目录下搜索,虽然my_add.h 在当面目录下,但是所处位置为/mylib/include/ 位置太深了,而搜索不到。而在系统文件也找不到,所以报错。

   处理方法1.:告诉 编辑器  头文件的路径库的路径 和 库的名称(去掉lib 和后缀 为库名称)

 🏊:形成一个可执行程序,可能不仅仅依赖一个库, gcc 默认是动态链接的,所以当我们包含了#include<stdio.h>的时候,实际上进行的动态链接,所以整体是动态链接的,如果整个可执行程序只有静态库,那么可执行程序是静态链接的。

    处理方法2:我们可以把头文件,静态库 安装在系统头文件目录和库目录下

这种把头文件和库安装系统头文件和库中就是安装 

  运行:

 

 2. 生成动态库

生成动态库的一些操作和静态库是类似的

 我们依然是对 my_add.c  my_sub.c 进行编译生成my_add.o  my_sub.o文件,和静态库不同的是,我们需要的是   gcc -c  -fPIC 文件名(fPIC  产生位置无关码)

 接下来的思路也是和静态库类似,对.o文件进行打包。静态库对.o文件打包的操作是

ar -rc (归打), 动态库也需要归打,但是已经不需要 ar -rc 了,因为编译器gcc 就可以默认

生成对应的动态库。只需要 gcc -shared -o ........

我们已经生成了一个动态库,接下来和静态库类似,我们需要创建一个目录,里面放着动态库libmymath.so 和相关头文件。 

 

我们依然可以通过 tar czf mylib.tgz mylib 打包给用户 然后用户再解压tar xzf mylib.tgz

在这里我们不重复静态库操作了,直接拷贝给test目录下。

接下来我们使用mylib这个库进行编译链接 

我们已经告诉了库文件,路径和库名称了,但是我们告诉的是gcc ,当gcc 把程序编译完之后,和gcc已经没有关系了,程序运行起来,os 和shell 也需要知道库的位置在哪里。而我们的库没在系统路径下,os无法找到。

方法一:我们可以把库放到系统库中。类似静态库的操作

方法二:动态库在进行链接的时候,系统除了在系统库中寻找,还会在库环境变量中寻找,我们可以把mylib/Libmymath.so 添加到库环境变量中。 

但是上述操作将环境变量导入系统库环境变量是临时有效的,当我们断开服务器重新登录

时,系统库环境变量将不会存在/lib

 方法三:配置文件(永久生效方法)

再vim  lt.conf 文件中,添加/lib 库的路径

 方法四:(永久有效)动态链接


相关文章:

  • 在 Linux(Ubuntu / CentOS 7)上快速搭建我的世界 MineCraft 服务器,并实现远程联机,详细教程
  • 【C语言】深入理解指针(1)
  • Docker应用部署之mysql篇(day5)
  • 用Python掌握算法:初学者指南
  • springboot+mybatisplus
  • MySQL安装与卸载
  • 开源webmail邮箱客户端rainloop的分支版本SnappyMail 设置发件人允许多重身份
  • Linux一步部署主DNS服务器
  • 《DepMamba : Progressive Fusion Mamba for Mutilmodal Depression Detection》论文精读笔记
  • (九)Spring Webflux
  • 深度学习 Note.1
  • 海康HTTP监听报警事件数据
  • 从 MySQL 到时序数据库 TDengine:Zendure 如何实现高效储能数据管理?
  • 破局离散制造:主数据管理驱动数字化转型的实践与启示
  • Rabbitmq消息被消费时抛异常,进入Unacked 状态,进而导致消费者不断尝试消费(上)
  • BC93 公务员面试
  • 16-CSS3新增选择器
  • 从子查询到连接:提升数据库查询性能的 7 种方法
  • 生成式AI课程 比较好
  • C++:重载操作符
  • 第1现场|无军用物资!伊朗港口爆炸已遇难40人伤1200人
  • 澎湃思想周报丨数字时代的育儿;凛冬已至好莱坞
  • 加拿大今日大选:房价、印度移民和特朗普,年轻人在焦虑什么?
  • 校长套取学生伙食费设小金库,重庆通报6起违反八项规定典型问题
  • 高璞任中国第一汽车集团有限公司党委常委、副总经理
  • 持续更新丨伊朗内政部长:港口爆炸已致14人死亡