Perché devo definire LD_LIBRARY_PATH con un export ogni volta che faccio funzionare la mia domanda?
-
22-08-2019 - |
Domanda
Ho qualche codice che utilizza alcune librerie condivise (codice C su GCC). Quando si compila devo definire esplicitamente l'inclusione e la directory di libreria utilizzando -I e -L, dal momento che non sono nei posti standard. Quando provo a eseguire il codice, ottengo il seguente errore:
./sync_test
./sync_test: error while loading shared libraries: libsync.so: cannot open shared object file: No such file or directory
Tuttavia, procedere come segue, tutto funziona bene:
export LD_LIBRARY_PATH="/path/to/library/"
./sync_test
Ora, la cosa strana è che questo funziona solo una volta. Se provo e faccio funzionare sync_test ancora ottengo lo stesso errore a meno che faccio funzionare l'ordine di esportazione prima. Ho provato ad aggiungere il seguente al mio .bashrc, ma non faceva alcuna differenza:
LD_LIBRARY_PATH="/path/to/library/"
Soluzione
Usa
export LD_LIBRARY_PATH="/path/to/library/"
nel vostro .bashrc in caso contrario, sarà disponibile solo per colpire e non tutti i programmi si avvia.
Prova bandiera -R/path/to/library/
quando si sta collegando, farà l'aspetto del programma in tale directory e non sarà necessario impostare le variabili di ambiente.
EDIT: Sembra che -R
è Solaris solo, e sei su Linux
Un modo alternativo sarebbe quello di aggiungere il percorso /etc/ld.so.conf
ed eseguire ldconfig
. Si noti che questo è un cambiamento globale che si applica a tutti i binari collegati dinamicamente.
Altri suggerimenti
Si dovrebbe evitare di impostare LD_LIBRARY_PATH
nel vostro .bashrc
. Vedere "Why LD_LIBRARY_PATH is bad
" per ulteriori informazioni.
Utilizzare l'opzione del linker -rpath durante il collegamento in modo che il linker dinamico sa dove trovare libsync.so
durante l'esecuzione.
gcc ... -Wl,-rpath /path/to/library -L/path/to/library -lsync -o sync_test
EDIT:
Un altro modo sarebbe quello di utilizzare un wrapper come questo
#!/bin/bash
LD_LIBRARY_PATH=/path/to/library sync_test "$@"
Se sync_test
inizia tutti gli altri programmi, che potrebbero finire con le librerie a /path/to/library
che può o non può essere destinati.
Hai fatto 'export' nel tuo .bashrc?
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"/path/to/library"
Si può semplicemente mettere tutto su una sola riga:
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/path/to/library" ./sync_test
Dovrebbe rendere le cose un po 'più facile, anche se non cambia nulla fondamentali
Invece di override del percorso di ricerca della libreria a runtime con LD_LIBRARY_PATH, si potrebbe invece cuocere nella stessa binario con rpath
. Se si collega con GCC aggiungendo -Wl,-rpath,<libdir>
dovrebbe fare il trucco, se ci si collega con ld è solo -rpath <libdir>
.
Cosa si può anche fare, se si tratta di qualcosa che è stato installato sul sistema, è quello di aggiungere la directory che contiene le librerie condivise al file /etc/ld.so.conf , o fare un nuovo file in /etc/ld.so.conf.d /
(ho controllato sia la distribuzione RHEL5 e Ubuntu quindi penso che sia generico per linux)
Il programma ldconfig farà in modo che siano a livello di sistema inclusi.
Si veda il seguente link per maggiori informazioni: www.dwheeler.com/secure-programs/Secure-Programs- HOWTO / dlls.html
Si potrebbe aggiungere nel codice di un sistema di chiamata con la nuova definizione:
sprintf(newdef,"export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:%s:%s",ld1,ld2);
system(newdef);
Ma, io non lo so che è la soluzione rigth ma funziona.
Saluti