为什么有这么多符号链接?

Why so many symbolic links?

安装Opencv 2.4.9后,我发现它在/usr/local/lib中创建了很多符号link。比如说,对于 libopencv_core.so.2.4.9,当我使用 ls -l 时,它显示

...
libopencv_core.so -> libopencv_core.so.2.4
libopencv_core.so.2.4 -> libopencv_core.so.2.4.9
libopencv_core.so.2.4.9
...

我的问题是,既然它已经把真正的共享库 libopencv_core.so.2.4.9 放在了 /usr/lcoal/lib 中,为什么还要为它创建一个符号 link,甚至另一个符号 link 到那个符号 link?

将真正的共享库放在其他地方并在 /usr/local/lib 中为它们创建符号 link 是否更好?

这是 Linux 系统上非常常用的程序,因为它允许您更改 .so 的最新版本(在您的情况下为 .so.2.4.9),而应用程序 运行只知道他们需要 link 第一个 .so .

因此所有程序都加载第一个 .so,然后通过符号 links,最终加载当前安装的版本。

如果按照您的建议进行(只需复制硬 .so),那么所有程序都会抱怨找不到合适的版本(在您的情况下为 2.4.9)。也许将来你将你的 openCV 升级到 2.4.10,你的所有程序都将停止工作。

一些项目实际上强制 linking 到某些主要或中等版本。因此,例如,如果您只保证您的程序适用于 2.4 版本,那么您将 link 将其设置为 .so.2.4 而不是 .so 。

最后它只是帮助分配兼容性。

第二个 libopencv_core.so.2.4(别名 "soname")和第三个 libopencv_core.so.2.4.9(别名 "real name")文件允许您更新库(在本例中为 OpenCV),并且仍然支持想要使用这些库的旧版本的程序。

$ ldd a.out
libopencv_core.so.2.4 => /path/to/lib/libopencv_core.so.2.4

运行 ldd,您可以看到可执行文件没有 linked 到 "real name" 库? 原因:用于处理库升级。考虑两种情况。

  1. 具有向后兼容性的库升级 => 安装程序(或 ldconfig )可以更新现有的 "soname" link(例如 libopencv_core.so.2.4)以指向更新的"real name" 库(例如 libopencv_core.so.2.4.10)和我们较旧的可执行文件现在将加载升级后的库。
  2. 没有向后兼容性的库升级 => 安装程序将创建新的 "soname" link(例如 libopencv_core.so.3.0)以指向新的 "realname" 库(例如例如 libopencv_world.so.3.0.0 )。在此之后构建的程序可以 link 到较新的库,而较旧的程序将继续加载较旧的 soname ( libopencv_core.so.2.4 ).
  3. 指向的库

关于,第一个符号link libopencv_core.so(别名"linker name")是 linker。对于像 -lopencv_core 这样的标志,gcc 在库名称和搜索前加上 lib 前缀和 .so 后缀。所以它需要一个名称为 libopencv_core.so 的文件,因此需要第一个符号 link。它从不在程序运行时使用。此外,如果愿意将 "soname" link 作为 gcc 命令行参数而不是 -lopencv_core,您将永远不需要此软 link.

这里有更好的解释(1)。