Perché devo definire con un export LD_LIBRARY_PATH ogni volta che ho eseguito la mia applicazione?

Ho del codice che utilizza alcune librerie condivise (codice c gcc). Durante la compilazione devo definire in modo esplicito la comprendono e la biblioteca directory utilizzando-I e -L, dal momento che non sono in posti standard. Quando cerco di eseguire il codice, ho 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, effettuare le seguenti operazioni, tutto funziona bene:

export LD_LIBRARY_PATH="/path/to/library/"
./sync_test

Ora, la parte strana è che questo funziona solo una volta. Se provo ad eseguire sync_test di nuovo ottengo lo stesso errore a meno che non ho eseguito il comando di esportazione prima. Ho provato ad aggiungere il seguente al mio .bashrc, ma non avrebbe fatto alcuna differenza:

LD_LIBRARY_PATH="/path/to/library/"
Penso che tutti questi suggerimenti sono cattivi, chiaramente un bug con Linux. Perché non compilare tempo L percorso non è stato passato a runtime?
È possibile impostare un percorso con -rpath, ma questo di solito non è consigliabile in quanto poi impone che il percorso su altri sistemi di vedere il secondo commento stackoverflow.com/a/695539/168175

OriginaleL’autore Paul Wicks | 2009-03-29

7 Replies
  1. 40

    Utilizzare

    export LD_LIBRARY_PATH="/path/to/library/"

    .bashrc in caso contrario, sarà solo disponibile per bash e non tutti i programmi di start.

    Provare -R/path/to/library/ bandiera quando si sta collegando, ti fanno sembrare il programma nella directory e non è 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 collegati dinamicamente i binari.

    doh! Avrei dovuto sapere che. Molto grazie.
    Utilizzare -Wl,-rpath (se passando per cc) o -rpath (se passando per ld) come più portatile che -R.
    -rpath può essere problematico, vedere wiki.debian.org/RpathIssue per una discussione
    Per la compatibilità, -R è anche supportato da GNU ld, anche se, come accennato nel commento di @awoodland, tale è indesiderato. (“Top 10 software commerciale errori” anche, direi)

    OriginaleL’autore brian-brazil

  2. 44

    Si dovrebbe evitare di impostare LD_LIBRARY_PATH nel .bashrc. Vedere Perché LD_LIBRARY_PATH è male“ per ulteriori informazioni.

    Utilizzare l’opzione del linker -rpath, mentre il collegamento in modo che il linker dinamico sa dove trovare libsync.so durante il runtime.

    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 "[email protected]"

    Se sync_test avvio di altri programmi, si potrebbe finire utilizzando le librerie a /path/to/library che possono o non possono essere intesi.

    Che davvero non aiuta se si sposta l’applicazione a macchina di qualcun altro e non vogliono mettere la biblioteca dello stesso /path/to che è previsto in fase di collegamento. Mentre -rpath, è certamente utile per gli amministratori di sistema e distro fornitori, credo sia presuntuoso per un individuo.
    Anche se, la prima dichiarazione di “evitare l’impostazione di LD_LIBRARY_PATH .bashrc” sono d’accordo con il 100%. Una terra di mezzo soluzione che ho usato è uno script bash $HOME/bin/programma che imposta locale LD_LIBRARY_PATH e poi esegue il file /path/to/reale/myprogram.
    Hai ragione. Uno non può presumere dove qualcuno vuole che la loro librerie. Nel caso In cui c’è un rapporto fisso tra bin/ e lib/, qualcosa di simile -rpath $ORIGIN/../lib potrebbe essere più appropriato. C’è anche un programma in grado di modificare il rpath in eseguibili ELF chiamato chrpath.
    Sono d’accordo con l’uso di un wrapper script di shell. Voglio aggiornare la mia risposta.
    Grazie per il suggerimento. Nessuna delle cose citate nell’articolo sono davvero problemi nel mio caso (questo codice è mai sta per essere eseguito su una macchina da me), ma io sicuramente tenere a mente se ho mai incontrato un problema simile.

    OriginaleL’autore sigjuice

  3. 10

    Ha fatto si ‘esporta’.bashrc?

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"/path/to/library"

    OriginaleL’autore bedwyr

  4. 10

    Si può solo 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 fondamentale

    Questa sintassi è meraviglioso… soprattutto se alcuni dei vostri comportamento del programma è basato su transitoria le variabili di ambiente come TMP o TMPDIR

    OriginaleL’autore

  5. 4

    Invece di rilevante percorso di ricerca della libreria a runtime con LD_LIBRARY_PATH, si potrebbe invece cuocere in un file binario con rpath. Se si collega con GCC aggiunta di -Wl,-rpath,<libdir> dovrebbe fare il trucco, se si collega con ld è solo -rpath <libdir>.

    OriginaleL’autore fgp

  6. 2

    Ciò che si può fare, se è qualcosa che hai installato sul vostro sistema, è quello di aggiungere la directory che contiene le librerie condivise per il tuo /etc/ld.così.conf file, o fare un nuovo file in /etc/ld.così.conf.d/

    (Ho sia controllato RHEL5 e distribuzione Ubuntu, quindi penso che è generico per linux)

    Il ldconfig programma di assicurarsi che essi sono a livello di sistema incluso.

    Si veda il seguente link per ulteriori informazioni:
    http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/dlls.html

    OriginaleL’autore Roalt

  7. 0

    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 giusta soluzione, ma funziona.

    Riguarda

    OriginaleL’autore user3916212

Lascia un commento