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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3839756/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 23:32:55  来源:igfitidea点击:

How do applications resolve to different versions of shared libraries at run time?

linuxshared-libraries

提问by nisah

I'm a noob to how shared libraries work on linux. I am trying to understand how do applications resolve different revisions of the same shared library at run-time on linux.

我不知道共享库如何在 linux 上工作。我试图了解应用程序如何在 linux 上运行时解析同一共享库的不同修订版。

As far as I understand, a shared library has three "names", for example,

据我了解,一个共享库有三个“名称”,例如,

  1. libmy.so.1.2 (real-name i.e. the actual obj file)
  2. libmy.so.1 (SONAME, which is embedded in the actual obj file)
  3. libmy.so (linker name, provided to the linker at link time and embedded in executable)
  1. libmy.so.1.2(实名即实际的obj文件)
  2. libmy.so.1(SONAME,嵌入在实际的 obj 文件中)
  3. libmy.so(链接器名称,在链接时提供给链接器并嵌入到可执行文件中)

When you install the library via LDCONFIG, it will create the following symbolic links

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

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

Now lets say I compile another version of the same library with the following real-name, libmy.so.2.0. The SONAME by guidelines would be libmy.so.2.0

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

At application link time what is the linker name that I would provide with the "-l" flag. Following the guidelines I read (http://www.dwheeler.com/program-library/Program-Library-HOWTO/x36.html), wouldn't it have to be libmy.so and if so, how will both versions of the obj file be distinguished ?

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

采纳答案by paxdiablo

Versioning of shared objects works as follows:

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

When you create a shared object, you give it both a real name and an soname. These are used to install the shared object (which creates both the object and a link to it).

当你创建一个共享对象时,你给它一个真实的名字和一个soname. 这些用于安装共享对象(创建对象和指向它的链接)。

So you can end up with the situation:

所以你可以结束这种情况:

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

with xyz.so.1.5possessing the SONAMEof xyz.so.1.

xyz.so.1.5拥有的SONAMExyz.so.1

When the linker links in xyz.so, it follows the links all the way to xyz.so.1.5and uses its SONAMEof xyz.so.1to store in the executable. Then, when you runthe executable, it tries to load xyz.so.1which will point to a specific xyz.so.1.N(not necessarily version 1.5).

当链接器链接 in 时xyz.so,它会一直跟随链接xyz.so.1.5并使用它的SONAMEofxyz.so.1存储在可执行文件中。然后,当您运行可执行文件时,它会尝试加载xyz.so.1指向特定xyz.so.1.N(不一定是 1.5 版)的文件。

So you could install xyz.so.1.6and update the xyz.so.1link to point to it instead and already-linked executables would use that instead.

因此,您可以安装xyz.so.1.6和更新xyz.so.1链接以改为指向它,并且已经链接的可执行文件将使用它。

One advantage of this multi-layer method is that you can have multiple potentially incompatible libraries of the same name (xyz.so.1.*, xyz.so.2.*) but, within each major version, you can freely upgrade them since they're supposed to be compatible.

这种多层方法的一个优点是您可以拥有多个同名 ( xyz.so.1.*, xyz.so.2.*) 的潜在不兼容库,但在每个主要版本中,您可以自由升级它们,因为它们应该是兼容的

When you link new executables:

当您链接新的可执行文件时:

  • Those linking with xyz.sowill get the latest minor version of the latest major version.
  • Others linking with xyz.so.1will get the latest minor version of a specific major version.
  • Still others linking with xyz.so.1.2will get a specific minor version of a specific major version.
  • 那些链接xyz.so将获得最新主要版本的最新次要版本。
  • 链接的其他人xyz.so.1将获得特定主要版本的最新次要版本。
  • 还有其他链接xyz.so.1.2将获得特定主要版本的特定次要版本。

Now keep that last paragraph in mind as we examine your comment:

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

Now lets say I compile another version of the same library with the following real-name, libmy.so.2.0. The SONAME by guidelines would be libmy.so.2.0.

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

No, I don't believe so. The sonamewould be more likely to be libmy.so.2so that you can make minor updates to the 2.xstream and get the latest behaviour.

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

回答by Didier Trosset

At application link time, if you specify -lmy, the linker will search for a file named libmy.so. It will find this file, and link you executable with it. If this file is a symbolic link, then your application will be linked with the target of the symlink.

在应用程序链接时,如果指定-lmy,链接器将搜索名为libmy.so. 它将找到此文件,并将您的可执行文件与其链接。如果此文件是符号链接,则您的应用程序将与符号链接的目标链接。

Application link time is theplace to specify which version of the dynamic library you want to use with your application.

应用程序链接时间是指定要与应用程序一起使用的动态库版本地方。

回答by guest

  1. Libs have different versions in the name.
  2. Packages with name "lib" have only libs and have different versions in the name.
  3. System will compile only with the latest library, unless you define a different one.
  4. The application uses only those libraries that it needs. Check ldd , readelf.
  5. Apps contain a link .so and .pc file, check rpm system for what. https://fedoraproject.org/wiki/Packaging:Guidelines?rd=Packaging#Devel_Packages
  1. Libs 在名称上有不同的版本。
  2. 名称为“lib”的包只有 libs 并且名称中有不同的版本。
  3. 除非您定义不同的库,否则系统将仅使用最新的库进行编译。
  4. 应用程序只使用它需要的那些库。检查 ldd ,阅读。
  5. 应用程序包含一个链接 .so 和 .pc 文件,检查 rpm 系统是什么。 https://fedoraproject.org/wiki/Packaging:Guidelines?rd=Packaging#Devel_Packages