我对共享库和操作系统的工作原理有点困惑。
第一个问题:操作系统如何管理共享库?如何唯一地指定它们?通过文件名或其他一些(比如说ID)的东西?或者通过完整的路径?!
第二个问题:我首先知道编译和链接代码时,链接器需要访问共享库(.so)来执行链接,然后在执行编译程序的这个阶段之后,OS加载共享库,这库可能位于不同的位置(我错了吗?)但是我不明白操作系统如何知道在哪里查找共享库,是可执行文件中编码的库信息(名称?路径?还是什么?!)?
答案 0 :(得分:0)
编译程序时,必须在构建中明确指定库(语言运行时除外),否则不会包含它们。有一些标准库目录,例如,您可以指定-lfoo
,它会自动在各种常用目录中查找libfoo.a
或libfoo.so
,例如/usr/lib
,{{ 1}}等等。
但请注意,/usr/local/lib
之类的名称通常是实际库文件名的符号链接,可能类似于libfoo.so
。这样,如果需要对ABI进行向后不兼容的更改(某些结构的布局可能会改变,比方说),那么新版本的库将变为libfoo.so.1
,并且与旧版本链接的二进制文件仍然存在不受影响。
因此,链接器遵循符号链接,并将对版本化名称libfoo.so.2
的引用插入到可执行文件中,而不是未版本名称libfoo.so.1
。它也可以插入完整路径,但通常不会这样做。相反,当运行可执行文件时,系统搜索路径(在系统范围libfoo.so
中配置)用于查找库。
(实际上,/etc/ld.so.conf
只是库搜索路径的人类可读来源;使用ld.so.conf
命令将其编译为/etc/ld.so.cache
中的二进制形式以获得速度。为什么每次更改系统上的可共享库时都需要运行ldconfig
。)
这是对正在发生的事情的非常简化的解释。这里没有涉及更多内容。 Here和here是一些可能对构建过程有用的参考文档。 here是系统可执行加载程序的描述。