ldconfig kann keine Verknüpfung zu bestimmten Dateien herstellen

ldconfig kann keine Verknüpfung zu bestimmten Dateien herstellen

Ich habe es ATLAS(mit Netlib LAPACK) in einem Docker-Image installiert und ldconfigerhalte 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.sonicht, aber ich bin verwirrt, warum es versucht, nach dieser Datei zu suchen, da libtatlas.soes 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.soist der Soname von /usr/local/lib/libtatlas.so. ldconfigversucht, 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.soerstellt 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.3etc. 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 ATLASbesteht 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 patchelfkann 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 sharedErstellen Sie dann die Bibliotheken.

Verwenden Sie einen Befehl wie diesen, readelf -d libtatlas.so | grep sonameum 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.

verwandte Informationen