Warum muss ich jedes Mal, wenn ich meine Anwendung ausführe, LD_LIBRARY_PATH mit einem Export definieren?
Lesezeit: 5 Minuten
Paul Wick
Ich habe Code, der einige gemeinsam genutzte Bibliotheken verwendet (C-Code auf gcc). Beim Kompilieren muss ich die Include- und Bibliotheksverzeichnisse explizit mit -I und -L definieren, da sie nicht an den Standardorten liegen. Wenn ich versuche, den Code auszuführen, erhalte ich die folgende Fehlermeldung:
./sync_test
./sync_test: error while loading shared libraries: libsync.so: cannot open shared object file: No such file or directory
Gehen Sie jedoch wie folgt vor, alles funktioniert einwandfrei:
Nun, das Merkwürdige daran ist, dass dies nur einmal funktioniert. Wenn ich versuche, sync_test erneut auszuführen, erhalte ich denselben Fehler, es sei denn, ich führe zuerst den Exportbefehl aus. Ich habe versucht, meiner .bashrc Folgendes hinzuzufügen, aber es hat keinen Unterschied gemacht:
LD_LIBRARY_PATH="/path/to/library/"
Ich denke, all diese Vorschläge sind schlecht – eindeutig ein Fehler mit Linux. Warum wird L-Pfad zur Kompilierungszeit nicht an die Laufzeit übergeben?
– Benutzer1129143
4. Januar 2012 um 4:00 Uhr
Sie können einen Pfad mit festlegen -rpathaber dies ist normalerweise nicht wünschenswert, da es diesen Pfad dann anderen Systemen aufzwingt – siehe zweiter Kommentar zu stackoverflow.com/a/695539/168175
– Flexo ♦
4. Januar 2012 um 4:24 Uhr
Sigisaft
Sie sollten das Setzen vermeiden LD_LIBRARY_PATH in deiner .bashrc. Sehen “Why LD_LIBRARY_PATH is bad“ für mehr Informationen.
Verwenden Sie die Linker-Option -rPfad beim Verlinken, damit der dynamische Linker weiß, wo er zu finden ist libsync.so während der Laufzeit.
Wenn sync_test andere Programme startet, verwenden sie möglicherweise die Bibliotheken in /path/to/library was beabsichtigt sein kann oder nicht.
Das hilft wirklich nicht, wenn Sie die Anwendung auf den Computer einer anderen Person verschieben und diese die Bibliothek nicht in den gleichen /Pfad/zu legen möchte, den Sie zum Zeitpunkt der Verknüpfung erwartet haben. Während -rpath für Systemadministratoren und Distributionsanbieter sicherlich nützlich ist, halte ich es für vermessen, dies von einer Einzelperson festzulegen.
– Tom
30. März 2009 um 3:56 Uhr
Obwohl, Ihrer ersten Aussage “Vermeiden Sie das Setzen von LD_LIBRARY_PATH in Ihrer .bashrc” stimme ich zu 100% zu. Eine Mittelwegslösung, die ich verwendet habe, ist ein Bash-Skript $HOME/bin/myprogram, das den lokalen LD_LIBRARY_PATH festlegt und dann /path/to/real/myprogram ausführt.
– Tom
30. März 2009 um 3:58 Uhr
Sie haben Recht. Man kann nicht annehmen, wo jemand seine Bibliotheken haben will. Falls es eine feste Beziehung zwischen bin/ und lib/ gibt, könnte etwas wie -rpath $ORIGIN/../lib angemessener sein. Es gibt auch ein Programm namens chrpath, das den rpath in ausführbaren ELF-Dateien ändern kann.
– Sigissaft
30. März 2009 um 6:32 Uhr
Ich stimme der Verwendung eines Wrapper-Shell-Skripts zu. Ich werde meine Antwort aktualisieren.
– Sigissaft
30. März 2009 um 6:35 Uhr
Danke für den Tipp. Keines der im Artikel erwähnten Dinge ist in meinem Fall wirklich ein Problem (dieser Code wird von mir immer nur auf einem Computer ausgeführt), aber ich werde sie auf jeden Fall berücksichtigen, wenn ich jemals auf ein ähnliches Problem stoße.
– Paul Wick
31. März 2009 um 4:20 Uhr
Brian-Brasilien
Verwenden
export LD_LIBRARY_PATH="/path/to/library/"
in Ihrer .bashrc andernfalls ist es nur für Bash verfügbar und nicht für Programme, die Sie starten.
Versuchen -R/path/to/library/ -Flag, wenn Sie verlinken, wird das Programm in diesem Verzeichnis suchen und Sie müssen keine Umgebungsvariablen setzen.
EDIT: Sieht so aus -R ist nur Solaris, und Sie verwenden Linux.
Eine alternative Möglichkeit wäre, den Pfad zu hinzuzufügen /etc/ld.so.conf und Renn ldconfig. Beachten Sie, dass dies eine globale Änderung ist, die für alle dynamisch verknüpften Binärdateien gilt.
Verwenden -Wl,-rpath (bei Weitergabe an cc) oder -rpath (bei Weitergabe an ld) als tragbarer als -R.
Aus Kompatibilitätsgründen wird -R auch von GNU ld unterstützt, obwohl dies, wie im Kommentar von @awoodland erwähnt, unerwünscht ist. (“Top 10 kommerzieller Softwarefehler” sogar, würde ich sagen)
– Jörgensen
4. Januar 2012 um 5:21 Uhr
Sie können das alles einfach in eine Zeile schreiben:
Anstatt den Bibliothekssuchpfad zur Laufzeit mit LD_LIBRARY_PATH zu überschreiben, könnten Sie ihn stattdessen mit in die Binärdatei selbst backen rpath. Wenn Sie mit GCC verknüpfen, fügen Sie hinzu -Wl,-rpath,<libdir> sollte den Trick machen, wenn Sie mit ld verlinken, ist es nur -rpath <libdir>.
Roalt
Was Sie auch tun können, wenn Sie es auf Ihrem System installiert haben, ist, das Verzeichnis, das die gemeinsam genutzten Bibliotheken enthält, zu Ihrem hinzuzufügen /etc/ld.so.conf Datei oder erstellen Sie eine neue Datei in /etc/ld.so.conf.d/
(Ich habe sowohl die RHEL5- als auch die Ubuntu-Distribution überprüft, daher denke ich, dass sie für Linux generisch ist.)
Das Programm ldconfig stellt sicher, dass sie systemweit eingebunden werden.
Ich denke, all diese Vorschläge sind schlecht – eindeutig ein Fehler mit Linux. Warum wird L-Pfad zur Kompilierungszeit nicht an die Laufzeit übergeben?
– Benutzer1129143
4. Januar 2012 um 4:00 Uhr
Sie können einen Pfad mit festlegen
-rpath
aber dies ist normalerweise nicht wünschenswert, da es diesen Pfad dann anderen Systemen aufzwingt – siehe zweiter Kommentar zu stackoverflow.com/a/695539/168175– Flexo
♦
4. Januar 2012 um 4:24 Uhr