=Start=
缘由:
补充系统知识
正文:
参考解答:
我们通常把一些公用函数制作成函数库,供其它程序使用(代码的复用)。函数库可分为静态库和动态库两种:
- 静态库在程序编译时会被链接到目标代码中,程序运行时将不再需要该静态库;
- 动态库在程序编译时并不会被链接到目标代码中,而是在程序运行时才被载入,因此在程序运行时还需要动态库存在。
动态库和静态库二者的不同点在于代码被载入的时刻不同。
静态库的代码在编译过程中已经被载入可执行程序,因此体积比较大。动态库(共享库)的代码在可执行程序运行时才载入内存,在编译过程中仅简单的引用,因此代码体积比较小。
静态情况下,把库直接加载到程序中,而动态库链接的时候,它只是保留接口,将动态库与程序代码独立,这样就可以提高代码的可复用度,和降低程序的耦合度。
静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。
1.什么是库?
在Windows平台和Linux平台下都大量存在着库。从本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。由于Windows和Linux的本质不同,因此二者库的二进制是不兼容的。本文仅限于介绍Linux下的库。
2.库的种类
Linux下的库有两种:静态库和动态库(共享库)。二者的不同点在于代码被载入的时刻不同。
- 静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。
- 共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小。
3.库存在的意义
库是别人写好的现有的,成熟的,可以复用的代码,你可以使用但要记得遵守许可协议。
现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。共享库的好处是,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。
4.在Linux下如何生成库文件?
Linux下静态库的后缀是.a,它的产生分两步:
Step 1.由源文件编译生成一堆.o,每个.o里都包含这个编译单元的符号表;
Step 2.用ar命令将很多.o转换成.a,成为静态库;
Linux下动态库的后缀是.so,它由gcc加特定参数编译产生。
例如:
$ gcc -fPIC -c *.c
$ gcc -shared -Wl,-soname, libfoo.so.1 -olibfoo.so.1.0 *.
5.库文件是如何命名的,有没有什么规范?
在Linux下,库文件一般放在/usr/lib和/lib下(64位系统对应的是/usr/lib64和/lib64):
- 静态库的名字一般为libxxxx.a,其中xxxx是该lib的名称;
- 动态库的名字一般为libxxxx.so.major.minor,xxxx是该lib的名称,major是主版本号, minor是副版本号。
6.如何知道一个可执行程序依赖哪些库
ldd命令可以查看一个可执行程序依赖的共享库,例如:
# ldd /bin/ln
libc.so.6 => /lib/libc.so.6 (0×40021000)
ld-linux.so.2 => /lib/ld-linux.so.2 (0×40000000)
可以看到ln命令依赖于libc库和ld-linux库。
7.可执行程序在执行的时候如何定位共享库文件?
当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径。
此时就需要系统动态载入器(dynamiclinker/loader),对于elf格式的可执行程序,是由ld-linux.so*来完成的。
它先后搜索elf文件的DT_RPATH段,环境变量LD_LIBRARY_PATH,/etc/ld.so.cache文件列表,/lib/,/usr/lib目录,找到库文件后将其载入内存。
- (仅ELF文件)使用可执行文件中DT_RPATH区域设置的属性,如果DT_RUNPATH被设置,那么忽略DT_RPATH(在我的Linux对应的是RPATH和RUNPATH);
- 使用环境变量LD_LIBRARY_PATH,如果可执行文件中有 set-user-id/set-group-id 会被忽略;
- (仅ELF文件)使用可执行文件中DT_RUNPATH区域设置的属性;
- 从/etc/ld.so.cache缓存文件中查找;
- 从默认路径/lib、/usr/lib文件目录中查找。
8.在新安装一个库之后如何让系统能够找到它?
如果安装在/lib或者/usr/lib下,那么ld默认能够找到,无需其他操作。
如果安装在其他目录,需要将其添加到/etc/ld.so.cache文件中,步骤如下:
1.编辑/etc/ld.so.conf文件,加入库文件所在目录的路径。
2.运行ldconfig,该命令会重建/etc/ld.so.cache文件。
参考链接:
- 静态库和动态库的优缺点 #详细
http://chriszeng87.iteye.com/blog/1186094 - Linux动态库相关知识整理 #详细
http://www.zkt.name/linuxgong-xiang-ku-de-chuang-jian-yu-shi-yong/ - Linux静态库和动态库 #详细
http://www.cnblogs.com/feisky/archive/2010/03/09/1681996.html - 技巧:Linux 动态库与静态库制作及使用详解 #比较系统
https://www.ibm.com/developerworks/cn/linux/l-cn-linklib/ - Linux下C调用静态库和动态库 #不错
http://answerywj.com/2016/10/10/Linux%E4%B8%8BC%E8%B0%83%E7%94%A8%E9%9D%99%E6%80%81%E5%BA%93%E5%92%8C%E5%8A%A8%E6%80%81%E5%BA%93/ - Linux下的静态库、动态库和动态加载库 #不错
http://www.techug.com/linux-static-lib-dynamic-lib - Linux下动态库(.so)和静态库(.a)
http://blog.csdn.net/felixit0120/article/details/7652907 - Linux系统中“动态库”和“静态库”那点事儿
http://blog.jobbole.com/107977/ - 静态库和动态库
http://leanote.com/blog/post/57907b2cab644133ed01bbf3 - 静态库与动态库的使用
https://www.gitbook.com/book/leon_lizi/-framework-/details - Linux下编译链接动态库
http://hbprotoss.github.io/posts/linuxxia-bian-yi-lian-jie-dong-tai-ku.html - Linux下静态、动态库(隐式、显式调用)的创建和使用及区别
http://blog.csdn.net/star_xiong/article/details/17301191
=END=
《 “静态库和动态库” 》 有 7 条评论
Linux下同时连接动态库和静态库
http://github.tiankonguse.com/blog/2017/05/14/lib-static-dynamic.html
`
Linux下链接库时使用-L来指定路径,使用-l来指定库名。默认情况下优先找动态库,找不到了再找静态库。
如果直接使用-static或者-dynamic会使所有库都使用这种形式链接,显示不是我们想要的。
当我们想要为某些库链接静态库,某些链接静态库,其余的按默认链接,则需要下面的样子:
-L./lib/test/ -Wl,-Bstatic -ltest #指定静态库
-L./lib/test/ -Wl,-Bdynamic -ltest #指定动态库
-Wl,-Bdynamic #恢复默认设置
`
在Linux下,如何强制让GCC静态链接? #nice
https://www.zhihu.com/question/22940048
技巧:Linux 动态库与静态库制作及使用详解
https://www.ibm.com/developerworks/cn/linux/l-cn-linklib/index.html
`
三种标准库链接方式选项及对比
全静态
全动态
半静态 (libgcc,libstdc++)
`
Linux gcc编译生成静态库和共享动态库的过程
https://typecodes.com/cseries/gccgensharedlib.html
各种静态编译的 *nix 工具
https://github.com/andrew-d/static-binaries
将简单的shell升级为完全交互式的TTY
http://www.4hou.com/technology/6248.html
一文弄懂Java和C中动态链接机制
https://juejin.im/post/5c5266926fb9a049b41ce30b
`
概念
模块、符号和链接
静态链接和动态链接
语言层面的对比
编译期的C/C++
静态链接库和共享库
编译期的Java
编译期对比
运行期的C/C++
运行期的Java
动态加载
动态链接的对比
总结
Ref
`
静态库和动态库区别
https://www.yanbinghu.com/2019/06/27/47343.html
linux下制作静态库
https://www.yanbinghu.com/2019/07/10/23906.html
动态库的制作与两种使用方式
https://www.yanbinghu.com/2019/07/18/38654.html
吴章金: 深度剖析 Linux共享库的“位置无关”实现原理
https://mp.weixin.qq.com/s/yOgTcj_ZwU5cyiIm3tVp3A
吴章金: 如何创建一个*可执行*的共享库
https://mp.weixin.qq.com/s?__biz=MzAwMDUwNDgxOA==&mid=2652666419&idx=1&sn=eec88fbb6649bb79972cc6be13ba7688
知名压缩软件 xz 被发现有后门,影响有多大?如何应对?
https://www.zhihu.com/question/650826484/answer/3448806357
`
大意是一个做测试的老哥因为服务器的风扇很吵,然后去检查发现sshd服务占用了大量的CPU资源(CPU发热多嘛),然后他发现在liblzma(就是xz的部分)占用了大量的CPU,然后他就想去查查到底哪部分代码跑的那么慢,结果调试时发现,这部分居然没有对应符号表。
啥是符号表呢,简单来说源代码到编译成程序时,会将源码和二进制程序做个对应,当程序出问题时,就能方便你查找到对应源码,因为这个恶意后门代码本身就是以二进制程序的方式插入进来的,没有经过这个源码到程序的编译过程,自然就没有符号表咯,那这个插入的部分,到底在隐藏什么?
测试老哥越想越不对劲,于是就有了上面这个邮件,可以说要不是这老哥的敬业水平和技术水平之高如此可见一斑,换其它任何一个草台班子,这个鸡脚都不会漏出来。
`