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 库的路径
方法四:(永久有效)动态链接