背景
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静 态库
动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。 一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文 件的整个机器码 在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个 过程称为动态链接(dynamic linking) 动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚 拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。
编写自己的库
math.c
myprint.c
静态库
首先先建立.h文件和.c文件,一个用来声明,一个用来定义。
我们对文件进行-c进行.c到.o二进制文件的处理
执行命令ar -rc lib(xxx).a (xxx).o (xxx).o归档一个打包好的二进制文件
也可以创建一个Makefile,用来统一操作
系统中gcc头文件默认搜索路径
系统中库文件默认搜索路径
将文件拷贝到系统的默认搜索路径下就叫库的安装,win中的安装本质就是用的这种方法,别人使用只需要有.h和.o文件就可以正常使用了
方法1:
方法2:
安装到系统的头文件默认搜索路径
安装到系统默认库文件搜索路径
执行文件 方法一
此时创建一个main.c函数去执行系统编译会显示无法识别头文件
此时我们需要在后面加上一个-lhello,其中l代表lib,hello是定义的时候是去hello这个文件夹取
删除系统默认路径下的库和头文件
方法2
其中-I是代表头文件搜索路径,-L是代表了库文件搜索路径,-lhello是代表了在该特定路径下去搜索l(hello)库文件
gcc main.c -I ./mklib/hello/include -L ./mklib/hello/lib/ -lhell
o
动态库
每一个动态库被加载到内存,映射到进程的地址空间,映射的位置可能是不一样的,但是库是相对地址,每一个函数采用偏移量的方式去寻找。库的起始地址+函数偏移量=访问库中所有函数。
Makefile编写
一次生成两个库 ,一个动态库,一个静态库
fPIC:
即使不加 fPIC 也可以生成 .so 文件,但是对于源文件有要求,例如因为不加 fPIC 编译的 so 必须要在加载到用户程序的地址空间的重定向所有表目,所以在它里面不能引用其它地方的代码。只需要记住生成动态编译时需要加fPIC即可。
.so
二进制文件生成.so动态库必须要加shared
当前文件夹
生成二进制文件
打包文件
可以看到文件已经打包好了
方法1:配置文件
sudo vim /etc/ld.so.conf.d/109.conf
复制出动态库所在的文件路径放到该配置文件中
编译
gcc main.c -I ./mklib/output/include/ -L ./mklib/output/lib/ -lhello
安装库连接
sudo ldconfig
查看动态连接
运行
方法2:配置环境变量
查看library的环境变量路径
在该路径下添加文件夹中动态库的路径,成功后可运行,但是该方法的缺陷是每次退出服务器就要重置