Reference
https://segmentfault.com/a/1190000016417397
https://segmentfault.com/a/1190000016433947
https://segmentfault.com/a/1190000016433897
链接器的作用
将目标文件 + 静态链接库 + 动态链接库 => 可执行文件
什么是静态链接?
目标文件 到 可执行文件
每个目标文件,都有代码段、数据段,还有一些符号表。静态链接就是把每个目标文件的数据段和代码段,根据执行顺序,复制到可执行文件里。
- 可执行文件和目标文件一样,也是由代码段和数据段组成。
- 每个目标文件中的数据段都合并到了可执行文件的数据段,每个目标文件当中的代码段都合并到了可执行文件的代码段。
- 目标文件当中的符号表并没有合并到可执行文件当中,因为可执行文件不需要这些字段。
可执行文件和目标文件没有什么本质的不同,可执行文件区别于目标文件的地方在于,可执行文件有一个入口函数,这个函数也就是我们在C语言当中定义的main函数,main函数在执行过程中会用到所有可执行文件当中的代码和数据。
静态库 例如 libc.a
假设这样一个应用场景,基础设计团队设计了好多实用并且功能强大的工具函数,业务团队需要用到里面的各种函数。每次新添加其中一个函数,业务团队都要去找相应的实现文件并修改链接选项。使用静态库就可以解决这个问题。静态库在Windows下是以.lib为后缀的文件,Linux下是以.a为后缀的文件。
什么是动态链接?
动态库
动态库(Dynamic Library),又叫共享库(Shared Library),动态链接库等,在Windows下就是我们常见的大名鼎鼎的DLL文件了,Windows系统下大量使用了动态库。在Linux下动态库是以.so为后缀的文件,同时以lib为前缀,比如进行数字计算的动态库Math,编译链接后产生的动态库就叫做libMath.so。从名字中我们知道动态库也是库,本质上动态库同样包含我们已经熟悉的代码段、数据段、符号表。只不过动态库的使用方式以及使用时间和静态库不太一样。
动态链接
动态库允许使用该库的可执行文件仅仅包含对动态库的引用而无需将该库拷贝到可执行文件当中。也就是说,同静态库进行整体拷贝的方式不同,对于动态库的使用仅仅需要可执行文件当中包含必要的信息即可,为了方便理解,你可以将可执行文件当中保存的必要信息仅仅理解为需要记录动态库的名字就可以了,如图所示,同静态库相比,动态库的使用减少了可执行文件的大小。
ldd 命令
用来查看可执行文件,需要哪些动态链接库,常用于来排查问题
https://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/ldd.html