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尋找需要修改的位置。

相關內容