it-swarm.it

Come funzionano i numeri SO (oggetto condiviso)?

Sono consapevole che gli oggetti condivisi su Linux usano "così numeri", vale a dire che alle diverse versioni di un oggetto condiviso vengono assegnate estensioni diverse, ad esempio:

  • example.so.1
  • example.so.2

Capisco l'idea è di avere due file distinti in modo tale che su un sistema possano esistere due versioni di una libreria (al contrario di "DLL Hell" su Windows). Mi piacerebbe sapere come funziona in pratica? Spesso vedo che example.so è in effetti un collegamento simbolico a example.so.2 dove .2 è l'ultima versione. In che modo quindi un'applicazione dipende da una versione precedente di example.so identificarlo correttamente? Ci sono delle regole su quali numeri si devono usare? O è semplicemente una convenzione? È vero che, a differenza di Windows in cui i file binari del software vengono trasferiti tra sistemi, se un sistema ha una versione più recente di un oggetto condiviso, viene automaticamente collegato alla versione precedente durante la compilazione dal sorgente?

Ho il sospetto che questo sia legato a ldconfig ma non sono sicuro di come.

127
user119

I binari stessi sanno da quale versione di una libreria condivisa dipendono e la richiedono in modo specifico. Puoi usare ldd per mostrare le dipendenze; i miei per ls sono:

$ ldd /bin/ls
    linux-gate.so.1 =>  (0xb784e000)
    librt.so.1 => /lib/librt.so.1 (0xb782c000)
    libacl.so.1 => /lib/libacl.so.1 (0xb7824000)
    libc.so.6 => /lib/libc.so.6 (0xb76dc000)
    libpthread.so.0 => /lib/libpthread.so.0 (0xb76c3000)
    /lib/ld-linux.so.2 (0xb784f000)
    libattr.so.1 => /lib/libattr.so.1 (0xb76bd000)

Come puoi vedere, indica ad es. libpthread.so.0, non solo libpthread.so.


Il motivo del collegamento simbolico è per il collegamento. Quando vuoi collegarti a libpthread.so direttamente, dai a gcc la bandiera -lpthread e aggiunge il prefisso lib e .so suffisso automaticamente. Non puoi dirlo per aggiungere il .so.0 suffisso, quindi il collegamento simbolico punta alla versione più recente della libreria per facilitarla

91
Michael Mrozek

I numeri nelle librerie condivise sono convenzioni utilizzate in Linux per identificare l'API di una libreria. In genere il formato è:

libFOO.so.MAJOR.MINOR

E come hai notato di solito c'è un collegamento simbolico da libFOO.so a libFOO.so.MAJOR.MINOR. ldconfig è responsabile dell'aggiornamento di questo collegamento alla versione più recente.

Il MAJOR viene in genere incrementato quando l'API cambia (i nuovi punti di ingresso vengono rimossi o i parametri o i tipi cambiati). Il MINOR viene in genere incrementato per le versioni di correzione dei bug o quando vengono introdotte nuove API senza interrompere le API esistenti.

Una discussione più ampia può essere trovata qui: Analizzare le librerie condivise

61
miguel.de.icaza

Le librerie condivise devono essere controllate in base al seguente schema:

blah.so.X.Y.Z

dove

  • X = versione ABI all'indietro incompatibile
  • Y = versione ABI retrocompatibile
  • Z = Solo modifiche interne - nessuna modifica all'ABI

In genere vedi solo la prima cifra come hello.so.1 perché la prima cifra è l'unica cosa necessaria per identificare la "versione" della libreria poiché tutte le altre cifre sono retrocompatibili.

ldconfig mantiene una tabella di quali librerie condivise sono disponibili su un sistema e dove esiste il percorso di quella libreria. Puoi verificarlo eseguendo:

ldconfig -p

Quando un pacchetto viene creato per qualcosa come Red Hat, le librerie condivise che vengono richiamate nel file binario verranno cercate e aggiunte come dipendenze del pacchetto al momento della creazione di RPM. Pertanto, quando vai a installare il pacchetto, il programma di installazione cercherà se hello.so.1 è installato sul sistema selezionando ldconfig.

Puoi vedere le dipendenze di un pacchetto facendo qualcosa del tipo:

rpm -qpR hello.rpm

Questo sistema (a differenza di Windows) consente più versioni di hello.so per essere installato su un sistema e utilizzato contemporaneamente da diverse applicazioni.

25
ascotan

libNAME.so è il nome file utilizzato dal compilatore/linker alla prima ricerca di una libreria specificata da -lNAME. All'interno di un file di libreria condiviso è presente un campo chiamato SONAME. Questo campo viene impostato quando la libreria stessa viene collegata per la prima volta a un oggetto condiviso (quindi) dal processo di compilazione. Questo SONAME è in realtà ciò che un linker archivia in un eseguibile a seconda dell'oggetto condiviso a cui è collegato. Normalmente SONAME ha la forma di libNAME.so.MAJOR e viene modificato ogni volta che la libreria diventa incompatibile con gli eseguibili esistenti collegati ad essa ed entrambe le principali versioni della libreria possono essere mantenute installate secondo necessità (anche se solo una verrà indicata per lo sviluppo come libNAME.so) Inoltre, per supportare facilmente l'aggiornamento tra le versioni secondarie di una libreria, libNAME.so.MAJOR è normalmente un collegamento a un file come libNAME.so.MAJOR.MINOR. È possibile installare una nuova versione secondaria e, una volta completata, il collegamento alla vecchia versione secondaria viene interrotto per puntare alla nuova versione secondaria che aggiorna immediatamente tutte le nuove esecuzioni per utilizzare la libreria aggiornata. Inoltre, vedi la mia risposta a Linux, GNU GCC, ld, script di versione e il formato binario ELF - Come funziona?

20
penguin359