Comprendo come definire oggetti condivisi inclusi al momento del collegamento/compilazione. Tuttavia, mi chiedo ancora come fanno gli eseguibili a cercare l'oggetto condiviso (*.so
librerie) al momento dell'esecuzione.
Ad esempio, la mia app a.out
richiama le funzioni definite in lib.so
biblioteca. Dopo la compilazione, sposto lib.so
in una nuova directory nel mio $HOME
.
Come posso dire a a.out
andare a cercarlo lì?
Risposta accettata:
L'HOWTO della libreria condivisa spiega la maggior parte dei meccanismi coinvolti e il manuale del caricatore dinamico entra più in dettaglio. Ogni variante di Unix ha il suo modo, ma la maggior parte usa lo stesso formato eseguibile (ELF) e ha linker dinamici simili¹ (derivati da Solaris). Di seguito riassumerò il comportamento comune con particolare attenzione a Linux; controlla i manuali del tuo sistema per la storia completa.
(Nota terminologica:la parte del sistema che carica le librerie condivise è spesso chiamata “dynamic linker”, ma a volte “dynamic loader” per essere più precisi. “Dynamic linker” può anche significare lo strumento che genera le istruzioni per il dynamic loader durante la compilazione un programma o la combinazione dello strumento di compilazione e del caricatore di runtime. In questa risposta, "linker" si riferisce alla parte di runtime.)
In poche parole, quando cerca una libreria dinamica (.so
file) il linker prova:
- directory elencate in
LD_LIBRARY_PATH
variabile di ambiente (DYLD_LIBRARY_PATH
su OSX); - directory elencate nel percorso dell'eseguibile;
- directory nel percorso di ricerca del sistema, che (almeno su Linux) è costituito dalle voci in
/etc/ld.so.conf
più/lib
e/usr/lib
.
Il rpath è memorizzato nell'eseguibile (è il DT_RPATH
o DT_RUNPATH
attributo dinamico). Può contenere percorsi assoluti o percorsi che iniziano con $ORIGIN
per indicare un percorso relativo alla posizione dell'eseguibile (ad es. se l'eseguibile è in /opt/myapp/bin
e il suo percorso è $ORIGIN/../lib:$ORIGIN/../plugins
quindi il linker dinamico cercherà in /opt/myapp/lib
e /opt/myapp/plugins
). Il rpath è normalmente determinato quando l'eseguibile viene compilato, con il -rpath
opzione per ld
, ma puoi cambiarlo in seguito con chrpath
.
Nello scenario che descrivi, se sei lo sviluppatore o il packager dell'applicazione e intendi installarla in un …/bin
, …/lib
struttura, quindi collega con -rpath='$ORIGIN/../lib'
. Se stai installando un binario predefinito sul tuo sistema, metti la libreria in una directory nel percorso di ricerca (/usr/local/lib
se sei l'amministratore di sistema, altrimenti una directory che aggiungi a $LD_LIBRARY_PATH
), oppure prova chrpath
.