我在Linux机器上安装了一系列二进制文件。它们需要libgfortran
库,但在执行时会显示以下消息:
error while loading shared libraries: libgfortran.so.2: cannot open shared object file: No such file or directory
该计算机已安装libgfortran
,但该库文件的名称为libgfortran.so.1.0.0
(与libgfortran.so.1
相关联。)
令我惊讶的是,只需创建一个符号链接libgfortran.so.2
到libgfortran.so.1
,如下所示:
ln -s /usr/lib64/libgfortran.so.1 /usr/lib64/libgfortran.so.2
这解决了我的问题,二进制文件能够运行,显然没有错误。
我的问题是 - 为什么他们甚至都跑了?
是否没有内置机制来检测API版本何时不同,还是仅基于文件名?
如果有API检测 - 那么应该没有符号错误吗?
的确,如果它们实际上是兼容的,那么在库之间使用不同的主要版本的目的是什么?
(回答问题:我的问题与libgfortran
无关,这只是一个说明性的例子。)
答案 0 :(得分:3)
为什么它一直在运行?
它运行是因为所有依赖符号都在.so中找到了
是否有内置机制来检测API版本差异?
可以使用符号版本控制支持,但您必须对其进行编程。这完全取决于开发人员是否使用它。
如果有API检测......?
同样,有符号版本可用,这不完全相同。
如果它仍然兼容,那么拥有不同主要版本的目的是什么
由开发人员决定。
但请注意,可能只是您使用的API元素在两个版本之间兼容。代码很可能会在后台静默地破坏您的数据,并且您将无法了解它直到下一行。
答案 1 :(得分:2)
对于与先前版本兼容的ABI版本,次要版本通常会增加。即当更新后者时,应用程序可以并将使用新的次要版本共享库。
对于与以前主要版本不兼容的ABI版本,主要版本通常会增加。
通常,一个共享库有三个文件系统名称,例如:
lrwxrwxrwx 1 max max 13 May 13 11:13 libfix.so -> libfix.so.0.0
lrwxrwxrwx 1 max max 13 May 13 11:13 libfix.so.0 -> libfix.so.0.0
-rwxrwxr-x 1 max max 1665544 May 13 11:13 libfix.so.0.0
未版本化的libfix.so
只是完全版本的符号链接。当您使用-lfix
链接器将您的应用程序与ld
链接时,会使用它。
libfix.so.0.0
是实际的共享库。但是,此库与-hlibfix.so.0
链接器选项链接:
-h name
-soname=name
When creating an ELF shared object, set the internal DT_SONAME
field to the specified name. When an executable is linked with a
shared object which has a DT_SONAME field, then when the executable
is run the dynamic linker will attempt to load the shared object
specified by the DT_SONAME field rather than the using the file
name given to the linker.
因此,应用程序启动时会发生的情况是运行时链接程序ld.so
实际上查找libfix.so.0
,这是指向具有相同主编号的最新版本共享库的符号链接。将libfix.so.0.0
更新为libfix.so.0.1
时,会更新这些符号链接以指向该新版本。现有的和新的应用程序在您下次启动或链接它们时开始使用新版本的共享库。