引子

静态库
ar打包形成静态库,归档文件单词缩写

ar -rc lib文件名.a 其他.o文件
ar是gnu归档工具,rc表示(replace 和 create)
示例:

发布:
本质就是放在一个文件夹里;这里mkdir 的-p参数表示可以一次创建多重目录;


使用:
多种方法
法1.拷贝到系统头文件的目录下
编译时要特殊处理
-IHello 的来源:-I是一个参数,Hello来源于libHello.a,被拆开的;
不建议把自己的库安装到系统目录中,自己的软件/库有问题,导致系统被污染
法2.

大写i

大写L

最后一个小写L,这里应该把参数和hello分开吧?(成功原因是gcc自动截取?未验证不确定)
答:不需要,与法1一样的用法。

动态库
形成与位置无关的二进制文件
1 libtest.so: ADD.o PRINT.o
2 gcc -shared -o libtest.so ADD.o PRINT.o
3 ADD.o: ADD.c
4 gcc -fPIC -c ADD.c -o ADD.o
5 PRINT.o:PRINT.c
6 gcc -fPIC -c PRINT.c -o PRINT.o
7
8 .PHONY:output
9 output:
10 mkdir -p myFile/lib
11 mkdir -p myFile/include
12 cp -rf *.h myFile/include
13 cp -rf *.so myFile/lib
14 rm *.o
15
16 .PHONY:clean
17 clean:
18 rm -rf *.o libtest.so myFile
和静态库区别:
生成:
编译时 + fPIC 参数;
打包用gcc,带-shared参数,告诉编译器这是一个动态库,不是一个可执行程序
使用:
先和静态用法一样进行编译链接,发现虽然生成了可执行文件,但却不能运行,显示找不到链接文件;回想链接操作是在告诉编译器动态库的位置,但我们知道动态库在被链接的时候只是在程序占了个位置,本身内容并没有被加入到可执行程序中,需要程序运行的时候再去自己找该部分内容,

7

也就是说动态库可以和可执行程序分批加载然而程序运行的时候并不知道库的内容在哪?此时就需要认为去配置,主要有以下几种方法:

需要告诉程序你的库在哪里,也可以把你的库放入操作系统仿官方库的位置(不建议,会污染官方库)
具体操作:
法1:
LD_LIBRARY_PATH
一般没配置的话,值为空

将动态库路径导入:

此时发现可正常运行;再看它所指向动态库,使我们自己的库

刚才导入的这个环境变量是内存级的,在退出终端再次登入的时候就会失效。
法2:
修改系统配置文件,/etc/ld.so.conf.d/,在该目录下创建后缀名为.conf的文件,以后自己的动态库路径均可放入该路径的该文件里,写完后使用命令 sudo ldconfig使其生效;

法3:
删除法2的配置
从截图中可以看出删除后程序还可继续运行,再更新配置后就不行了;
此时,我们再介绍一种方法:
创建软连接,在/lib64/目录下创建一个指向动态库的软连接即可

再来深入了解动态库的:
每一个动态库被加载到内存,映射到进程的地址空间,映射的位置可能不一样,
但是因为库里面是相对地址,每一个函数定位采用偏移量的方式寻找
换句话说,只要知道这个库的相对地址,库的起始地址
库的起始加载虚拟地址+函数偏移量 = 就可以在自己的地址空间访问库中所有函数。
总结:
静态库在被使用时已经被复制入形成的可执行程序中,属于绝对编址,为地址空间的地址;动态库采用相对编址;此外动态链接被使用时,除了在编译时需要和静态库一样告诉编译器库地址,更要在程序运行时告诉生成的可执行程序其地址,那为什么系统官方库不需要告诉呢,其实不然,都是要告诉的,不过系统一般将官方库采用环境变量法,会默认自己配置好;但个人的库一般不建议放入环境变量,导致官方库污染。
动静态库同时存在的情况,优先使用动态库,加-static参数可以强行使用静态库;没有动态库自动使用静态库

