应用程序如何在运行时解析为不同版本的共享库?

nis*_*sah 36 linux shared-libraries

我是共享库如何在linux上工作的菜鸟.我试图了解应用程序如何在Linux上运行时解析同一共享库的不同修订版.

据我所知,共享库有三个"名称",例如,

  1. libmy.so.1.2(实名即实际的obj文件)
  2. libmy.so.1(SONAME,嵌入在实际的obj文件中)
  3. libmy.so(链接器名称,在链接时提供给链接器并嵌入在可执行文件中)

通过LDCONFIG安装库时,它将创建以下符号链接

  • (2)=>(1)
  • (3)=>(2)

现在假设我使用以下实名libmy.so.2.0编译同一个库的另一个版本.指南中的SONAME是libmy.so.2.0

在应用程序链接时,我将使用"-l"标志提供什么链接器名称.按照我阅读的指南(http://www.dwheeler.com/program-library/Program-Library-HOWTO/x36.htm l),它不一定是libmy.so,如果是这样,两个版本将如何obj文件的区别?

pax*_*blo 42

共享对象的版本控制如下:

创建共享对象时,可以为其指定实名和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拥有的SONAMExyz.so.1.

当连接环节xyz.so,它遵循的链接一路xyz.so.1.5和使用它SONAMExyz.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将获得特定主要版本的特定次要版本.

在我们检查你的评论时,请记住最后一段:

现在让我说我用以下实名编译同一个库的另一个版本,libmy.so.2.0.指南中的SONAME将是libmy.so.2.0.

不,我不相信.该soname会更可能是libmy.so.2这样,你可以做轻微的更新到2.x流并获得最新的行为.

  • 你在写我的答案时抓住了我.现在我只能补充一点,如果OP很好奇,他可能会用`readelf`来检查他系统上预装的库的名字:`readelf -Wa /usr/lib/libstdc++.so.6 | grep SONAME`并了解指南如何付诸实践. (5认同)