Wie geben Sie den Speicherort von Bibliotheken für eine Binärdatei an? (Linux)

34

Für diese Frage verwende ich ein spezielles Beispiel, aber dies verallgemeinert so ziemlich jede Binärdatei unter Linux, die ihre abhängigen Bibliotheken nicht zu finden scheint. Ich habe also ein Programm, das wegen fehlender Bibliotheken nicht ausgeführt werden kann:

./cart5: error while loading shared libraries: libcorona-1.0.2.so: cannot open shared object file: No such file or directory

ldd beleuchtet das Problem:

linux-vdso.so.1 =>  (0x00007fff18b01000)
libcorona-1.0.2.so => not found
libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.3/libstdc++.so.6 (0x00007f0975830000)
libm.so.6 => /lib/libm.so.6 (0x00007f09755af000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007f0975399000)
libc.so.6 => /lib/libc.so.6 (0x00007f0975040000)
libz.so.1 => /lib/libz.so.1 (0x00007f0974e2b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0975b36000)

Corona ist jedoch installiert:

oliver@human$ find / -name libcorona-1.0.2.so 2> /dev/null

/usr/local/lib64/libcorona-1.0.2.so
/home/oliver/installed/corona-1.0.2/src/.libs/libcorona-1.0.2.so

Wie sage ich der Binärdatei, wo nach der "fehlenden" Bibliothek zu suchen ist?

Mala
quelle

Antworten:

43

Legen Sie für eine einmalige Verwendung die Variable LD_LIBRARY_PATHauf eine durch Doppelpunkte getrennte Liste der zu durchsuchenden Verzeichnisse fest. Dies ist analog zu PATHausführbaren Dateien, außer dass die Standardsystemverzeichnisse zusätzlich nach den durch die Umgebung angegebenen durchsucht werden.

LD_LIBRARY_PATH=/usr/local/lib64 ./cart5

Wenn Sie ein Programm haben, das Bibliotheken an einem nicht standardmäßigen Speicherort aufbewahrt und nicht in der Lage ist, sie selbst zu finden, können Sie ein Wrapper-Skript schreiben:

#!/bin/sh
if [ -n "$LD_LIBRARY_PATH" ]; then
  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib64
else
  LD_LIBRARY_PATH=/usr/local/lib64
fi
export LD_LIBRARY_PATH
exec /path/to/cart5 "$@"

Die Liste der Standardsystemverzeichnisse wird beibehalten /etc/ld.so.conf. Neuere Systeme ermöglichen es dieser Datei, andere Dateien einzuschließen. Wenn Ihre include /etc/ld.so.conf.d/*.confDatei so etwas wie enthält , erstellen Sie eine neue Datei /etc/ld.so.conf.d/mala.confmit dem Namen, die die Verzeichnisse enthält, die Sie hinzufügen möchten. /etc/ld.so.confFühren Sie nach der Änderung oder einer eingeschlossenen Datei die Ausführung /sbin/ldconfigaus, damit die Änderungen wirksam werden (dies aktualisiert einen Cache).

( LD_LIBRARY_PATHGilt auch für viele andere Unix - Varianten, darunter FreeBSD, NetBSD, OpenBSD, Solaris und Tru64. HP-UX hat SHLIB_PATHund Mac OS X hat DYLD_LIBRARY_PATH. /etc/ld.so.confHat Analoga auf den meisten Unix - Varianten , aber die Lage und die Syntax unterscheidet sich weiter verbreitet.)

Gilles 'SO - hör auf böse zu sein'
quelle
1
Fantastisch, vielen Dank. Ich hatte keine Ahnung von /etc/ld.so.conf und es wird mir in Zukunft sehr nützlich sein.
Mala
15

Wenn Sie LD_LIBRARY_PATH vermeiden möchten, können Sie dies auch während der Verknüpfung tun:

gcc -o exename -L/path/to/dynamiclib/ -lnameofLib \
    -Wl,-R/path/to/dynamiclib/ sourceCode1.c ...

Mit -Wl, ... werden zusätzliche Befehle an den Linker übergeben. In diesem Fall weisen Sie den Linker mit -R an, diesen Pfad als "Standardsuchpfad" für die .so-Datei zu speichern.

Ich mache mir Notizen zu vielen kleinen Tipps wie diesen auf meiner Website:

https://www.thanassis.space/tricks.html

ttsiodras
quelle
Wenn für die betreffende Bibliothek jedoch gemeinsam genutzte Bibliotheken zum Nachschlagen vorhanden sind, wird der in der Binärdatei gespeicherte Pfad nicht rekursiv auf die Suchvorgänge in der Unterbibliothek angewendet. Ich habe keinen anderen Weg gefunden, als LD_LIBRARY_PATH in der Umgebung festzulegen, die dann auf rekursive Lookups angewendet wird ...
Ethan
@Ethan: Stimmt. Was aber auch zutrifft, ist, dass Sie in den üblichen Szenarien, in denen Sie gemeinsam genutzte Bibliotheken für einige Binärdateien "packen" möchten, alle gemeinsam platzieren. ZB /opt/mypackage/bin/someBinarywerden Bibliotheken benötigt, in denen Sie speichern /opt/mypackage/lib/. Nahezu alle proprietären SWs, die unter / opt installiert werden, folgen dieser Regel - was bedeutet, dass der oben gezeigte Weg alle derartigen Installationen abdeckt. Sie fügen dann normalerweise auch einen Symlink unter / usr / bin hinzu, der auf die Binärdatei unter / opt verweist - in dem Wissen, dass der "Standardsuchpfad" das .sos unter dem entsprechenden /opt/.../libOrdner findet.
Ttsiodras
ja, in meinem Fall war ich will ein Paket testen , indem Sie die Verknüpfung gegen sein Build - Verzeichnis , anstatt zu installieren es ... (aber das Paket hatte mehrere interne .so ist mit einigen Interdependenzen ... Vielzahl von Umgehungen aber nur ärgerlich)
Ethan
0

Dies zeigt an, dass libcorona nicht im richtigen Pfad installiert ist. Verschieben Sie das libcorona-Verzeichnis in den richtigen Pfad. Das Problem wird behoben.

Rathi
quelle
Wie ist das besser als andere Antworten?
Toto
@Toto Im Gegensatz zu den anderen Antworten installieren Sie die Dateien im Grunde genommen manuell. Das bedeutet zwar nicht, dass diese Antwort besser ist, aber es ist eine Option, die in Betracht gezogen werden sollte (dies wird auch in Windows durch Kopieren von Bibliotheken nach ausgeführt) system32 / sysWOW64, wenn ihre Apps sie nicht finden können), nicht, dass dies empfohlen wird, da davon dringend abgeraten wird.
Tcll