我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.so
。ldconfig
嘗試將庫鏈接到它們的 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
尋找需要修改的位置。