Linux静态库和动态链接库的制作和使用

gcc的简单介绍

预处理(cpp)
把文本文件中的预处理指令全部展开,包括头文件包含,宏替换

gcc test.c -o test.i -E

编译(ccl)
编译预处理文件,生成对应硬件平台的汇编代码

gcc test.i -o test.s -S

汇编(as)
编译汇编代码,翻译为对应处理器的二进制机器码(生成二进制文件可重定向目标文件)

gcc test.s -o test.o -c

链接库
生成可执行文件

gcc test.o -o test -lc  //链接标准的c库
gcc test.o -o test -v  //查看当前编译链接的过程


对于上述编译过程,重点关注最后一步库文件的链接(gcc test.o -o hello -lc):链接实际上是将多个.o文件合并在一起的过程。这些 *.o 文件合并前是 ELF 格式,合并后也是 ELF 格式。

ELF代表Executable and Linkable Forma,是一种对可执行文件、目标文件和库使用的文件格式,跟Windows下的PE文件格式类似。ELF格式是是UNIX系统实验室作为ABI(Application Binary Interface)而开发和发布的,早已经是Linux下的标准格式了

ELF主要包括三种类型文件:

可重定位文件(relocatable):编译器和汇编器产生的.o文件,被Linker所处理

可执行文件(executable):Linker对.o文件进行处理输出的文件,进程映像

共享对象文件(shared object):动态库文件.so

ELF格式的合并,实际上就是将多个文件中各自对应的段合并在一起,形成一个统一的ELF文件。

在此过程中,必然需要对各个 *.o 文件中的静态数据(包括常量)、函数入口的地址做统一分配和管理,这个过程就叫做 重定位,因此未经链接的单独的 *.o 文件又被称为可重定位文件,经过链接处理合并了相同的段的文件称为可执行文件。

readelf -S test.o  //显示节区表内的所有信息,包括每个节的属性

readelf -h test.o  //显示在ELF文件头里包含的所有信息

readelf -s test.o  //显示符号表的信息,包含静态符号表(.symtab)和动态符号表(.dynsym)


静态库和动态库

静态库在程序编译链接时,会被完整地复制到可执行文件中。
通常以.a(在 Unix/Linux 系统下)或.lib(在 Windows 系统下)为文件扩展名。它实际上是一组目标文件(.o文件)的归档集合,包含了多个函数和变量的编译后的代码。

动态库在程序运行时才被加载到内存中,供程序调用,在 Unix/Linux 系统下通常以.so为扩展名,在 Windows 系统下通常以.dll为扩展名。动态库在磁盘上是独立的文件,包含可执行代码和数据,这些代码和数据在程序运行时可以被多个程序共享。

静态库命名规范
lib库名.后缀

对于动态库而言,在后缀后面还经常会带着版本号
lib库名.后缀.版本号  


制作静态库

首先写自己的C文件,例如编写a.c和b.c包含已经封装好的函数

然后编译a.c和b.c
 

gcc a.c -o a.o -c
gcc b.c -o b.o -c

将编译完的.o文件合并为一个静态链接库

ar crs libx.a a.o b.o

查看静态链接库中的*.o文件

ar -t libx.a

删除静态链接库中的*.o文件

ar d libx.a b.o

像静态库中增加*.o文件

 ar r libx.a b.o

提取静态库中*.o文件

 ar x libx.a

提取静态库中指定*.o文件

ar x libx.a a.o

静态库的调用,在主函数调用静态库的头文件,#include “xx.h"
编译时用gcc main.c -L./ -lxx -lyy //-L./指定在当前目录下,-l指定库名

制作动态库

gcc a.c -o a.o -c -fPIC
gcc b.c -o b.o -c -fPIC

gcc -shared -fPIC -o libx.so a.o b.o

运行动态库

动态库的最大特征,就是编译链接后程序并不包含动态库的代码,这些程序会在每次运行时,动态地去寻找并定位其所依赖的库文件中的模块,这是他们为什么被称为动态库的原因。也就是说,如果程序运行时找不到动态库,运行就会失败

为了解决找不到动态库的问题,假设我的库路径在/home/loading/lib


有两种解决方法
1、编译时预告

gcc main.c -o main -L. -lx -Wl,-rpath=/home/loading/lib/   //-Wl选项用于将后面的参数传递给链接器

2、将动态链接库路径添加到系统变量中

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/loading/lib
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值