Ala*_*lam 4 linux symlink libs
当我这样做时ls -l,/usr/lib我会看到很多带有"sameName.so.*.*"扩展名的库.
一个例子将有助于理解.
这是用于版本共享对象文件的技巧.这是一种避免由于延迟链接而产生的可怕DLL地狱的方法.
延迟链接(或后期绑定)的优点是可以更改可执行文件的组件,而无需实际重新链接这些可执行文件.这允许在第三方组件中修复错误,而不必运送新的可执行文件等.
缺点与优点完全相同.您的可执行文件可以发现它对底层库所做的假设已经改变,这可能会导致各种问题.
共享对象的版本控制是避免这种情况的一种方法.另一个不是共享对象,但也有利有弊,我不会在这里讨论.
举个例子,假设你有版本1 xyz.so.您有一个文件和指向该文件的符号链接:
pax> ls -al xyz*
-rw-r--r-- 1 pax paxgroup 12345 Nov 18 2009 xyz.so.1
lrwxrwxrwx 1 pax paxgroup 0 Nov 18 2009 xyz.so -> xyz.so.1
Run Code Online (Sandbox Code Playgroud)
现在,当您创建一个可执行文件exe1并将其链接时xyz.so,它将遵循符号链接,以便它xyz.so.1作为在运行时加载所需的内容存储在可执行文件中.
这样,当您升级共享库时:
pax> ls -al xyz*
-rw-r--r-- 1 pax paxgroup 12345 Nov 18 2009 xyz.so.1
-rw-r--r-- 1 pax paxgroup 67890 Nov 18 2009 xyz.so.2
lrwxrwxrwx 1 pax paxgroup 0 Nov 18 2009 xyz.so -> xyz.so.2
Run Code Online (Sandbox Code Playgroud)
你原来的可执行文件exe1将仍然加载共享对象的版本1.
但是,您现在创建的任何可执行文件(例如exe2)都将与共享对象的版本2链接.
实际的实现细节可能会有所不同(我的答案基于早期的UNIX,Linux似乎比仅仅遵循符号链接更智能地进行版本控制).IBM developerWorks有一篇很好的文章介绍了它是如何在这里完成的.
创建共享对象时,可以为其指定实名和soname.这些用于安装共享对象(它创建对象和链接到它).
所以你可以结束这种情况:
pax> ls -al xyz*
-rw-r--r-- 1 pax paxgroup 12345 Nov 18 2009 xyz.so.1.5
lrwxrwxrwx 1 pax paxgroup 0 Nov 18 2009 xyz.so.1 -> xyz.so.1.5
lrwxrwxrwx 1 pax paxgroup 0 Nov 18 2009 xyz.so -> xyz.so.1
Run Code Online (Sandbox Code Playgroud)
与xyz.so.1.5拥有的SONAME的xyz.so.1.
当连接环节xyz.so,它遵循的链接一路xyz.so.1.5和使用它SONAME的xyz.so.1在可执行文件存储.然后,当您运行可执行文件时,它会尝试加载xyz.so.1指向特定的xyz.so.1.N(不一定是版本1.5).
因此,您可以安装xyz.so.1.6并更新xyz.so.1链接以指向它,而已链接的可执行文件将使用它.
这种多层方法的一个优点是,您可以拥有多个可能不兼容的同名库(xyz.so.1.*,xyz.so.2.*),但是,在每个主要版本中,您可以自由升级它们,因为它们应该是兼容的.
链接新的可执行文件时:
xyz.so将获得最新主要版本的最新次要版本.xyz.so.1将获得特定主要版本的最新次要版本.xyz.so.1.2将获得特定主要版本的特定次要版本.libfoo.so.1.2.3libfoo.so.1.2.该名称实际上是在库二进制文件本身内部编写的,并将在链接时记录在可执行文件中.它通常是库的真实姓名(通常是最新版本)的符号链接.假设您安装了libfoo版本1:libfoo.so- > libfoo.so.1.0- > libfoo.so.1.0.0.你建立你的程序bar有-lfoo.它现在链接到libfoo并将libfoo.so.1.0在运行时加载由于SONAME.然后libfoo.so.1.0.1通过替换真正的二进制文件升级到修补但二进制兼容.bar仍然链接到libfoo.so.1.0,不需要重建.
现在假设你想构建一个baz利用libfoo v1.1中不兼容的更改的新程序.您安装了新版本,系统现在并行安装了两个版本:
libfoo.so.1.0 - > libfoo.so.1.0.1libfoo.so- > libfoo.so.1.1- >libfoo.so.1.1.0注意链接器名称已更新为最新版本(这是与您安装的标头对应的版本/usr/include).
您构建baz,并在运行时链接libfoo.so和加载libfoo.so.1.1.这不是bar仍然运行libfoo.so.1.0,不需要更新.
| 归档时间: |
|
| 查看次数: |
171 次 |
| 最近记录: |