为什么有这么多符号链接?
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" 库? 原因:用于处理库升级。考虑两种情况。
- 具有向后兼容性的库升级 => 安装程序(或
ldconfig
)可以更新现有的 "soname" link(例如 libopencv_core.so.2.4)以指向更新的"real name" 库(例如 libopencv_core.so.2.4.10)和我们较旧的可执行文件现在将加载升级后的库。
- 没有向后兼容性的库升级 => 安装程序将创建新的 "soname" link(例如 libopencv_core.so.3.0)以指向新的 "realname" 库(例如例如 libopencv_world.so.3.0.0 )。在此之后构建的程序可以 link 到较新的库,而较旧的程序将继续加载较旧的 soname ( libopencv_core.so.2.4 ).
指向的库
关于,第一个符号link libopencv_core.so(别名"linker name")是仅 linker。对于像 -lopencv_core
这样的标志,gcc 在库名称和搜索前加上 lib
前缀和 .so
后缀。所以它需要一个名称为 libopencv_core.so 的文件,因此需要第一个符号 link。它从不在程序运行时使用。此外,如果愿意将 "soname" link 作为 gcc 命令行参数而不是 -lopencv_core
,您将永远不需要此软 link.
这里有更好的解释(1)。
安装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" 库? 原因:用于处理库升级。考虑两种情况。
- 具有向后兼容性的库升级 => 安装程序(或
ldconfig
)可以更新现有的 "soname" link(例如 libopencv_core.so.2.4)以指向更新的"real name" 库(例如 libopencv_core.so.2.4.10)和我们较旧的可执行文件现在将加载升级后的库。 - 没有向后兼容性的库升级 => 安装程序将创建新的 "soname" link(例如 libopencv_core.so.3.0)以指向新的 "realname" 库(例如例如 libopencv_world.so.3.0.0 )。在此之后构建的程序可以 link 到较新的库,而较旧的程序将继续加载较旧的 soname ( libopencv_core.so.2.4 ). 指向的库
关于,第一个符号link libopencv_core.so(别名"linker name")是仅 linker。对于像 -lopencv_core
这样的标志,gcc 在库名称和搜索前加上 lib
前缀和 .so
后缀。所以它需要一个名称为 libopencv_core.so 的文件,因此需要第一个符号 link。它从不在程序运行时使用。此外,如果愿意将 "soname" link 作为 gcc 命令行参数而不是 -lopencv_core
,您将永远不需要此软 link.
这里有更好的解释(1)。