Linux库(一).动静态库的制作
一.何谓库
库是写好的现有的,成熟的,可以复⽤的代码。现实中每个程序都要依赖很多基础的底层库,不可能 每个⼈的代码都从零开始,因此库的存在意义⾮同寻常。
本质上来说库是⼀种可执⾏代码的⼆进制形式,可以被操作系统载⼊内存执⾏。库有两种:

二.静态库的制作
①.静态库的打包
静态库是一种归档文件,可以使用ar指令,将当前目录下生成的所有.o文件全部打包,生成一个.a文件,该文件就是静态库。.a文件(静态库)不同于tar生成的压缩包,它不需要解包,可以用gcc/g++直接链接,生成可执行程序。
打包指令:
ar -rc dest.a *.o
-rc选项:存在重复的文件就替换,没有重复的就创建。
注意:静态库的命名一般以lib作为开头,以.a作为结尾!

.o文件装的是代码实现,只不过是二进制的;而头文件囊括了.o里实现的所有接口名,相当于一份说明书。
②.使用静态库
那么如何使用库中的接口呢?答案是链接生成可执行程序时,时增加一个-l+真实文件名选项,以链接上库!!注意,一定要真实文件名,不能加lib和.a!
但还是编不过,wdf?找不到库?

原因在于gcc默认不会去当前工作目录下寻找非标准库的头文件或.a文件,所以这时还要添加一个
-L+指定路径选项,代表在指定目录下寻找.a文件:

这时就可以链接通过了。
总结:

gcc -o usercode usercode.c -I lib/include/ -L lib/mylib/ -lmyc
选项含义解析:
-I:指明头文件的搜索路径(告诉编译器
去哪里找头文件)。
,-L:指明库文件的搜索路径(告诉编译器
去哪里找库文件)。
-l:指明需要链接的库名称(去掉lib 前缀和.a/.so 后缀)。
为什么C/C++的标准库不需要这些-I、-L、-l选项?
因为gcc/g++编译器默认就认识系统的标准库,它们存放在特定的系统标准路径下(如/usr/include、/lib64),编译器会自动去这些路径检索并完成链接。若我们要链接任何非C/C++标准库(包括第三方库或我们自己写的库),都需要用这些选项明确指出。如果想要非官方库也不写这些选项,需要将第三方库安装到系统中。所谓安装,其实是把库对应的.h文件和.a文件拷贝到系统指定路径下!
为什么在链接生成可执行程序时,已经链接上对应静态库了,还要在一开始.c文件里包含库的头文件?
头文件存在的目的就是应付编译器检查以及给用户的说明书,真正找到库,链接库的,还是
-L,-l指令。
所谓将可执行程序与一个静态库链接,说白了就是把静态库里的相关接口实现拷贝给可执行程序里要用到这些接口的地方。
③.静态库的交付
为了方便使用,会将.a库文件和.h全部组织到一个特定目录下:

再用tar把目录及其内容压缩成一个压缩包,这个压缩包就是安装包!

④.makefile里完整的建库过程:

三.动态库的制作
①.打包
动态库的打包不是用ar指令,而是直接用gcc。动态库在内存中可以被多个进程共享,因此在打包动态库的时候,需要特殊选项shared和fPIC。
# 1. 产生位置无关码 (Position Independent Code)
# 必须使用 -fPIC 选项
gcc -fPIC -c mystdio.c mystring.c
# 2. 使用 -shared 选项进行动态库打包
gcc -shared -o libmyc.so mystdio.o mystring.o
• shared:表⽰⽣成共享库格式
• fPIC:产⽣位置⽆关码(positionindependentcode)
• 库名规则:libxxx.so
②.使用动态库
Ⅰ.使用指令
依旧要在.c文件链接生成可执行文件时,用-I,-l,-L选项链接上库:

Ⅱ.见鬼
但是在./执行可执行程序时,出问题了:

加过动态库所在的路径了,找不到是什么鬼???????
原因在于,用-I-L-l选项添加的路径,只是告诉了gcc。而./时,执行可执行程序所依赖的库,是需要让系统知道的!而系统!=gcc。系统不会去上面选项的指定路径下寻找动态库,它只会在/lib64或者/usr/local/路径下寻找。
那为什么静态库照样执行上面指令,不会出这个问题呢?
因为在形成可执行程序时,动态库的代码实现会自动拷贝到系统目录(lib64 or usr/local/)下,所以执行时,就不需要依赖静态库了。
Ⅲ.如何解决?
1.暴力一点,学静态库,直接把库拷贝到系统目录下。

2.软链接
在lib64下建个库(文件),用这个文件去软链接库的整条路径。

我不想去动系统文件,老蒯,有没有别的方法,有的兄弟,有的!
3.环境变量 LD_LIBRARY_PATH
操作系统除了在系统目录下查找动态库,也会在这个环境变量下查找。这玩意经常是空的,需要用户手动将动态库路径添加到这个环境变量下。
添加指令:

当然,这个环境变量是内存级的,进程一结束,终端一关,导进来的动态库路径就没了。
4.在 /etc/ld.so.conf.d/ 路径下添加配置文件
配置文件里面写入动态库的路径就行了。注意文件名可以随意取,但是要加后缀.conf。
添加配置文件:

写入路径:

最后别忘了要在系统重新加载配置文件:

四.动静态库混合链接
1.如果同时提供(同时打包.a和.so)动静态库,gcc/g++默认使用动态库!如果非要用静态库参与链接,必须链接时,在库名后添加static;反过来说,携带static,就必须存在对应的静态库:

只存在静态库,可执行程序只能对该库静态链接了。
2.linux系统下,默认情况下,安装的大部分库,都是动态库!
3.库:应用程序 = 1:n。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)