Come si specifica la posizione delle librerie in un binario? (Linux)


34

Per questa domanda userò un esempio specifico, ma in realtà questo generalizza praticamente a qualsiasi binario su Linux che non sembra trovare le sue librerie dipendenti. Quindi, ho un programma che non verrà eseguito a causa delle librerie mancanti:

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

ldd fa luce sul problema:

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)

Tuttavia, corona è installato:

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

Come faccio a dire al binario dove cercare la libreria "mancante"?

Risposte:


43

Per una volta, impostare la variabile LD_LIBRARY_PATH su un elenco separato da due punti di directory da cercare. Ciò è analogo a quello PATHdegli eseguibili, tranne per il fatto che le directory di sistema standard vengono ulteriormente ricercate dopo quelle specificate nell'ambiente.

LD_LIBRARY_PATH=/usr/local/lib64 ./cart5

Se hai un programma che mantiene le librerie in una posizione non standard e non è in grado di trovarle da sole, puoi scrivere uno script wrapper:

#!/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 "$@"

Viene conservato l'elenco delle directory di sistema standard /etc/ld.so.conf. I sistemi recenti consentono a questo file di includere altri file; se il tuo contiene qualcosa di simile include /etc/ld.so.conf.d/*.conf, crea un nuovo file chiamato/etc/ld.so.conf.d/mala.conf contenente le directory che desideri aggiungere. Dopo aver modificato /etc/ld.so.confo un file incluso, esegui /sbin/ldconfigle modifiche affinché abbiano effetto (questo aggiorna una cache).

( LD_LIBRARY_PATHSi applica anche a molti altri unice, tra cui FreeBSD, NetBSD, OpenBSD, Solaris e Tru64. HP-UX ha SHLIB_PATHe Mac OS X ha DYLD_LIBRARY_PATH. /etc/ld.so.confha analoghi sulla maggior parte degli unice ma la posizione e la sintassi differiscono maggiormente.)


1
Fantastico, grazie mille. Non avevo idea di /etc/ld.so.conf, e in futuro mi sarà molto utile.
Mala,

15

Se vuoi evitare LD_LIBRARY_PATH, puoi anche farlo, durante il collegamento:

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

Il -Wl, ... è usato per passare comandi extra al linker, e in questo caso, con -R dici al linker di memorizzare questo percorso come "percorso di ricerca predefinito" per il .so.

Tengo note di molti piccoli suggerimenti come questo, sul mio sito:

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


Ma se la libreria in questione ha librerie condivise da cercare, il percorso memorizzato nel file binario non viene applicato in modo ricorsivo alle ricerche della sotto-biblioteca. Non ho trovato un modo per aggirare questo se non quello di impostare LD_LIBRARY_PATH nell'ambiente, che poi viene applicato alle ricerche ricorsive ...
Ethan,

@Ethan: True. Ma ciò che è anche vero è che i soliti scenari in cui si desidera "impacchettare" librerie condivise per alcuni file binari sono quelli in cui sono stati messi tutti insieme; ad esempio, /opt/mypackage/bin/someBinaryavrai bisogno di librerie in cui archiviare /opt/mypackage/lib/. Praticamente tutti i SW proprietari installati sotto / opt seguono questa regola, il che significa che il modo sopra indicato coprirà tutte queste installazioni. Di solito aggiungeranno anche un link simbolico sotto / usr / bin che punta al binario sotto / opt - sapendo che il "percorso di ricerca predefinito" troverà .soi messaggi nella /opt/.../libcartella appropriata .
ttsiodras,

sì, nel mio caso volevo testare un pacchetto collegandolo alla sua directory di build piuttosto che installarlo ... (ma il pacchetto aveva diversi .so interni con alcune interdipendenze ... varietà di soluzioni alternative ma solo fastidiosi)
Ethan,

0

Questo indica che libcorona non è installato nel percorso corretto. Sposta la directory libcorona nel percorso corretto, il problema verrà risolto.


In che modo è meglio di altre risposte?
Toto

@Toto a differenza delle altre risposte, sostanzialmente stai installando manualmente i file ... Anche se questo non significa esattamente che questa risposta sia migliore, ma È un'opzione che dovrebbe essere considerata (le persone fanno questo anche in Windows copiando le librerie in system32 / sysWOW64 quando le loro app non riescono a trovarle), non è raccomandato, perché è fortemente scoraggiato.
Fino
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.