1. Shared Libraries(共享库) 和 Static Libraries(静态库)区别
- 共享库是以“.so”(Windows 平台为“.dll”,Mac OS 平台为“.dylib”)作为后缀的文件。所有和库有关的代码都在这一个文件中,程序在运行时引用它。使用共享库的程序只会引用共享库中它要用到的那段代码。
- 静态库是以“.a”(Windows平台为“.lib”)作为后缀的文件。所有和库有关的代码都在这一个文件中,静态库在编译时就被直接链接到了程序中。使用静态库的程序从静态库拷贝它要使用的代码到自身当中。
- 使用共享库可以减少程序中重复代码的数量,让程序体积更小。而且让你可以用一个功能相同的对象来替换共享对象,这样可以在增加性能的同时不用重新编译那些使用到该库的程序。但是使用共享库会小额增加函数的执行的成本,同样还会增加运行时的加载成本,因为共享库中的符号需要关联到它们使用的东西上。共享库可以在运行时加载到程序中,这是二进制插件系统最通用的一种实现机制。
- 静态库总体上增加了程序体积,但它也意味着你无需随时随地都携带一份要用到的库的拷贝。因为代码在编译时就已经被关联在一起,因此在运行时没有额外的消耗。
2. GCC 首先在/usr/local/lib
搜索库文件,其次在/usr/lib
,然后搜索-L
参数指定路径,搜索顺序和-L
参数给出路径的顺序一致。
3. 默认的 GNU 加载器ld.so
,按以下顺序搜索库文件:
- 首先搜索程序中
DT_RPATH
区域,除非还有DT_RUNPATH
区域。 - 其次搜索
LD_LIBRARY_PATH
。如果程序是setuid/setgid
,出于安全考虑会跳过这步。 - 搜索
DT_RUNPATH
区域,除非程序是setuid/setgid
。 - 搜索缓存文件
/etc/ld/so/cache
(停用该步可以使用-z nodeflib
参数) - 搜索默认目录
/lib
,然后/usr/lib
(停用该步请使用-z nodeflib
参数)。