ldconfig 无法链接到特定文件

ldconfig 无法链接到特定文件

ATLAS(使用 Netlib LAPACK)安装在 Docker 映像中,现在每次运行时ldconfig,都会出现以下错误:

ldconfig: Can't link /usr/local/lib//usr/local/lib/libtatlas.so to libtatlas.so
ldconfig: Can't link /usr/local/lib//usr/local/lib/libsatlas.so to libsatlas.so

当然,/usr/local/lib//usr/local/lib/libtatlas.so不存在,但我很困惑为什么它会尝试查找这个文件,因为libtatlas.so它不是符号链接:

root@cd00953552ab:/usr/local/lib# ls -la | grep atlas
-rw-r--r-- 1 root staff 15242054 Apr 27 08:18 libatlas.a
-rwxr-xr-x 1 root staff 17590040 Apr 27 08:18 libatlas.so
-rwxr-xr-x 1 root staff 17492184 Apr 27 08:18 libsatlas.so
-rwxr-xr-x 1 root staff 17590040 Apr 27 08:18 libtatlas.so

为什么会发生这种情况,有没有办法修复它/关闭此错误消息?

编辑:这是 Readelf 输出:

root@cd00953552ab:/usr/local/lib# eu-readelf -a /usr/local/lib/libatlas.so | grep SONAME
  SONAME            Library soname: [/usr/local/lib/libtatlas.so]

答案1

由于某种原因,可能与库的构建方式(更具体地说,链接)有关,它们将安装目录存储在 soname 中:因此libtatlas.so的 soname 是/usr/local/lib/libtatlas.soldconfig尝试将库链接到它们的 soname(如果不存在),在同一目录中:它找到,检查其 soname,确定需要从(目录和 soname 连接)到/usr/local/lib/libtatlas.so建立链接,并失败,因为不存在不存在。/usr/local/lib//usr/local/lib/libtatlas.so/usr/local/lib/libtatlas.so/usr/local/lib/usr/local/lib

解决此问题的适当方法是确保正确定义库的 sonames。通常,我期望libtatlas.so.3没有目录名称的等(版本取决于正在构建的库的 ABI 级别)。您可能需要重建库,或者找到正确构建的包......

或者,您可以使用编辑库的soname补丁ELF

patchelf --set-soname libtatlas.so /usr/local/lib/libtatlas.so

理想情况下,您应该重新链接使用此库构建的程序,因为它们也会嵌入 soname(您也可以使用 PatchELF 对其进行修补)。

在不断发展的系统中,您确实希望在 soname 中指定版本,但在容器中这可能并不重要 - 无论如何您都应该重建容器以进行升级。

答案2

在 BLAS 库的这个特殊情况下ATLAS。解决真正原因的方法是更正用于构建包的 makefile。

原因请参阅@Stephen Kitt 的回答。

然而,由于一个--set-soname 的错误在 中patchelf,patchelf 解决方案无法工作。

您的库路径包含“/usr/local”,因此我假设它是从源代码构建的。

检查文件$(SRC)/makes/Make.lib$(SRC)你的源代码根目录在哪里。

特别是这些行:

LDTRY:
    $(LD) $(LDFLAGS) -shared -soname $(LIBINSTdir)/$(outso) -o $(outso) \
       -rpath-link $(LIBINSTdir)  \
       --whole-archive $(libas) --no-whole-archive $(LIBS)

这里的soname 是不正确的:-soname $(LIBINSTdir)/$(outso)。将其更改为-soname $(outso),然后重建库即可解决此问题。

如果您已经成功构建,请更改 中的相应行$(BUILD)/lib/Makefile,其中$(BUILD)是构建库的目录。然后make shared构建库。

使用诸如之类的命令readelf -d libtatlas.so | grep soname检查生成的 .so 文件中的 soname。它不应包含任何目录部分。

如果找不到正确的makefile(例如使用不同版本的makefile ATLAS),请尝试grep -IR soname找到需要修改的位置。

相关内容