2015-08-20 14 views
5

Se voglio creare un programma C++ che si collega con una libreria statica, l'eseguibile finale conterrà sia il codice del mio programma, sia il codice della libreria (penso ...!). Ma non sono del tutto sicuro di cosa succede quando collego una libreria condivisa.Cosa viene aggiunto a un file eseguibile quando si collega a una libreria condivisa?

Supponiamo di collegarmi con una libreria denominata libfoo.so, specificando nel file CMakeLists.txt la riga target_link_libraries(${PROJECT_NAME} foo). Suppongo che l'eseguibile finale conterrà alcune informazioni su questa libreria, ma non sul codice completo. Cos'è questa altra informazione? Inoltre, la libreria deve essere chiamata esattamente libfoo.so sul sistema dell'utente?

+0

Nota: lo standard C++ in genere non supporta le librerie dinamiche. Il supporto più vicino al supporto esplicito che si ottiene è la dichiarazione sull'inizializzazione delle variabili del campo dei nomi che potrebbero essere ritardate dopo la prima istruzione di 'main'. La formulazione nello standard è altrettanto fuorviante, suppongo che l'unica interpretazione ragionevole sia "dopo l'inizio della prima affermazione di' main' ". –

+1

L'eseguibile ha un'intestazione che contiene informazioni in diverse sezioni. Se sei interessato ad esplorare le intestazioni, puoi usare l'utility linux 'read' per leggere le intestazioni su un eseguibile elfo. In particolare, saranno necessarie le opzioni '-d' e' -s' per visualizzare rispettivamente la sezione dinamica e la tabella dei simboli. – alvits

risposta

6

Quando si collega a una libreria dinamica, il linker aggiungerà una voce NEEDED nella sezione dinamica del programma. Quindi il caricatore dinamico li utilizzerà per localizzare la libreria e utilizzare la libreria per risolvere qualsiasi simbolo dinamico indefinito.

Si noti che non vi è alcuna connessione tra i simboli dinamici non definiti e le librerie dinamiche in cui dovrebbero essere trovati. A volte si trovano in un'altra libreria e possono accadere cose interessanti.

Il particolare nome memorizzato nella voce NEEDED dipende dal fatto che la biblioteca ha una voce SONAME nella sua sezione dinamica:

  • Se c'è un SONAME, quindi il suo contenuto verrà copiato alla NEEDED del programma
  • Se non è presente SONAME, il nome del file della libreria utilizzato nel comando linker verrà archiviato.

È possibile controllare i contenuti della sezione dinamica di una biblioteca o di un programma con:

$ objdump -p program 

Come è utilizzato nella pratica? Ebbene, la maggior parte (? Tutti) le distribuzioni linux utilizzano il seguente schema, con le librerie di sistema (prendere libfoo.so):

  • La biblioteca è installato come /usr/lib/libfoo.so.1.2 o qualunque versione che è.
  • I collegamenti simbolici a quella libreria denominata /usr/lib/libfoo.so.1 e /usr/lib/libfoo.so.
  • Il numero SONAME della libreria è libfoo.so.1.
  • Il percorso /usr/lib è impostato come percorso di libreria dinamico.

In questo modo, quando si collega con -lfoo troverà il link simbolico libfoo.so, ma registrerà il SONAME come libfoo.so.1. E quando il programma viene eseguito, troverà l'altro link simbolico e caricherà la libreria.

Questo trucco è usato in modo da poter installare un compatibile con ABI, migliorato libfoo.so.1.3 e un ABI compatibile più recente libfoo.so.2.1, e vecchio programma caricherà l'antica biblioteca mentre i nuovi compilation utilizzeranno la nuova libreria.

Si noti inoltre che le variabili di ambiente LD_PRELOAD, LD_LIBRARY_PATH e altre influiscono sul comportamento di runtime. Per ulteriori dettagli, è possibile leggere man ld.so

Problemi correlati