ldconfig は特定のファイルにリンクできません

ldconfig は特定のファイルにリンクできません

ATLASDocker イメージに(Netlib とともに)をインストールしましたLAPACKが、 を実行するたびに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

これを修正する適切な方法は、ライブラリの soname が正しく定義されていることを確認することです。通常、libtatlas.so.3ディレクトリ名のない etc. を期待します (バージョンは、ビルドされるライブラリの 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 が見つからない場合 (たとえば、 の別のバージョンを使用している場合ATLAS)、grep -IR soname変更する必要がある箇所を探してください。

関連情報