Ich habe es ATLAS
(mit Netlib LAPACK
) in einem Docker-Image installiert und ldconfig
erhalte jetzt jedes Mal, wenn ich es ausführe, die folgenden Fehler:
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
Existiert natürlich /usr/local/lib//usr/local/lib/libtatlas.so
nicht, aber ich bin verwirrt, warum es versucht, nach dieser Datei zu suchen, da libtatlas.so
es kein symbolischer Link ist:
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
Warum passiert dies und gibt es eine Möglichkeit, das Problem zu beheben bzw. diese Fehlermeldung abzuschalten?
Bearbeiten: Hier ist die Readelf-Ausgabe:
root@cd00953552ab:/usr/local/lib# eu-readelf -a /usr/local/lib/libatlas.so | grep SONAME
SONAME Library soname: [/usr/local/lib/libtatlas.so]
Antwort1
Aus irgendeinem Grund, der wahrscheinlich mit der Art und Weise zusammenhängt, wie die Bibliotheken erstellt (und genauer, verknüpft) wurden, haben sie ihr Installationsverzeichnis in ihrem Soname gespeichert: daher libtatlas.so
ist der Soname von /usr/local/lib/libtatlas.so
. ldconfig
versucht, Bibliotheken mit ihrem Soname zu verknüpfen, falls dieser nicht existiert, im selben Verzeichnis: es findet , prüft seinen Soname, stellt fest, dass eine Verknüpfung von (dem Verzeichnis und Soname zusammen) zu /usr/local/lib/libtatlas.so
erstellt werden muss , und schlägt fehl, weil nicht existiert./usr/local/lib//usr/local/lib/libtatlas.so
/usr/local/lib/libtatlas.so
/usr/local/lib/usr/local/lib
Die beste Möglichkeit, dies zu beheben, besteht darin, sicherzustellen, dass die Sonames der Bibliotheken korrekt definiert sind. Normalerweise würde ich libtatlas.so.3
etc. ohne Verzeichnisnamen erwarten (die Version hängt von der ABI-Ebene der zu erstellenden Bibliothek ab). Sie müssen die Bibliotheken wahrscheinlich neu erstellen oder ein korrekt erstelltes Paket finden ...
Alternativ können Sie den Sonamen einer Bibliothek bearbeiten mitAufnäherELF:
patchelf --set-soname libtatlas.so /usr/local/lib/libtatlas.so
Idealerweise sollten Sie die mit dieser Bibliothek erstellten Programme erneut verknüpfen, da darin auch der Soname eingebettet ist (Sie können das auch mit PatchELF patchen).
In einem sich entwickelnden System möchten Sie wirklich eine Version im Soname angeben, aber in einem Container spielt das wahrscheinlich keine Rolle – Sie sollten den Container für Upgrades ohnehin neu erstellen.
Antwort2
In diesem speziellen Fall der BLAS-Bibliothek ATLAS
besteht die Lösung für die eigentliche Ursache darin, das zum Erstellen des Pakets verwendete Makefile zu korrigieren.
Die Begründung finden Sie in der Antwort von @Stephen Kitt.
Aufgrund einerFehler von --set-sonamein patchelf
kann die Patchelf-Lösung nicht funktionieren.
Ihr Bibliothekspfad enthält „/usr/local“, daher gehe ich davon aus, dass er aus dem Quellcode erstellt wird.
Überprüfen Sie die Datei $(SRC)/makes/Make.lib
. Dort $(SRC)
befindet sich das Stammverzeichnis Ihres Quellcodes.
Insbesondere diese Zeilen:
LDTRY:
$(LD) $(LDFLAGS) -shared -soname $(LIBINSTdir)/$(outso) -o $(outso) \
-rpath-link $(LIBINSTdir) \
--whole-archive $(libas) --no-whole-archive $(LIBS)
Der Soname ist hier falsch: -soname $(LIBINSTdir)/$(outso)
. Ändern Sie ihn in -soname $(outso)
, und erstellen Sie anschließend die Bibliothek neu, um das Problem zu beheben.
Falls Sie bereits einen erfolgreichen Build haben, ändern Sie die entsprechende Zeile in $(BUILD)/lib/Makefile
, wobei $(BUILD)
sich das Verzeichnis zum Erstellen der Bibliothek befindet. make shared
Erstellen Sie dann die Bibliotheken.
Verwenden Sie einen Befehl wie diesen, readelf -d libtatlas.so | grep soname
um den Soname in der resultierenden .so-Datei zu überprüfen. Er sollte keinen Verzeichnisteil enthalten.
Wenn Sie das richtige Makefile nicht finden können (z. B. wenn Sie eine andere Version von verwenden ATLAS
), versuchen Sie grep -IR soname
, die Stelle zu finden, die geändert werden muss.