库符号链接是否用于加载库?

库符号链接是否用于加载库?

有人告诉我,“我确实知道在加载库时,Linux 上不使用符号链接。”

然而,这对我来说似乎不正确。当我在 Linux 中闲逛时,我常常不得不修复损坏的符号链接。

我可以找到有关符号链接、它们如何工作以及如何创建的信息。

我可以找到有关共享库和静态库及其工作原理的信息。

但我找不到任何描述加载库时如何使用符号链接的库加载过程的文档。特别是当库有多个版本时。

有人可以向我指出描述如何使用符号链接在 Linux 中加载库的文档吗?

更新

经过一番研究,我相信这个人暗示.so加载库时不使用符号链接。

答案1

您不太可能找到任何描述动态库如何使用符号链接的文档,因为这两个概念是在不同的抽象级别实现的。符号链接属于文件系统,对应用程序和动态库是透明的。对于程序来说,文件只是文件,无论它是真实文件还是符号链接。所有内部工作都隐藏在操作系统内核中。

答案2

事实证明我不理解库的链接过程。

当一个库在编译后链接到一个程序时,它链接到.so.XX该库的soname(通常是文件,其中XX是版本号),而不是版本.so

ldd在应用程序上运行会显示以下内容:

> ldd /opt/GSix/bin/MyApplication 
linux-vdso.so.1 (0x00007ffcefff0000)
/usr/lib64/libsyslognb.so (0x00007fe1eacbc000)
librt.so.1 => /lib64/librt.so.1 (0x00007fe1eaab4000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fe1ea897000)
libQt5Widgets.so.5 => /usr/local/Trolltech/Qt-5/lib/libQt5Widgets.so.5 (0x00007fe1e99f5000)
libQt5Gui.so.5 => /usr/local/Trolltech/Qt-5/lib/libQt5Gui.so.5 (0x00007fe1e9143000)
libQt5Core.so.5 => /usr/local/Trolltech/Qt-5/lib/libQt5Core.so.5 (0x00007fe1e894d000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fe1e85d2000)
libm.so.6 => /lib64/libm.so.6 (0x00007fe1e82d4000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fe1e80c2000)
libc.so.6 => /lib64/libc.so.6 (0x00007fe1e7d24000)

每个库都有一个.so指向主要.so.X版本的符号链接版本。但ldd显示该应用程序未链接到该.so版本。

这是有道理的,因为它允许在系统上安装库的多个版本,并且每个应用程序只会加载它需要的版本,而不会与其他版本冲突。

例如,您的curl 库可能如下所示:

16 libcurl.so -> libcurl.so.4
16 libcurl.so.4 -> libcurl.so.4.4.0
387K libcurl.so.4.4.0

16 libcurl.so.3 -> libcurl.so.3.1.0
387K libcurl.so.3.1.0

假设 MyApplication 链接到版本 4,YourApplication 链接到版本 3。

如果两个应用程序都在查找 libcurl.so,则 YourApplication 将无法加载,因为libcurl.so它是指向 .so 的符号链接libcurl.so.4

这就是为什么应用程序需要加载.so.X版本而不是.so版本。

相关内容