Di solito quando costruisci oggetti condivisi (.so) ti occupi anche delle versioni aggiungendo suffissi come mylib.so.2.3.1. Per assicurarti che i tuoi programmi possano caricare questa libreria o altre versioni successive, crei collegamenti con nomi
mylib.so -> mylib.so.2.3.1
mylib.so.2 -> mylib.so.2.3.1
mylib.so.2.3 -> mylib.so.2.3.1
Quindi, tutto ciò che segue .so rappresenta version.sub-version.build (o simile) Inoltre, è possibile che più di una versione della stessa lib coesista con questo schema, e tutto ciò che è necessario per far passare i programmi all'utilizzo di un particolare versione deve disporre dei collegamenti appropriati.
Il binario ELF collegato dinamicamente (se un'altra libreria o un eseguibile) utilizza il nome dell'oggetto condiviso o soname per identificare la libreria a cui l'eseguibile deve essere collegato al momento dell'esecuzione.
Quando una libreria viene creata come libreria condivisa ELF, l'editor di collegamento in fase di compilazione inserisce un campo DT_SONAME nell'eseguibile che rappresenta il SONAME della libreria nella libreria stessa. Il DT_SONAME è definito nello standard ELF come:
Questo elemento contiene l'offset della tabella delle stringhe di una stringa con terminazione null, fornendo il nome dell'oggetto condiviso. L'offset è un indice nella tabella registrata nel
DT_STRTAB
iscrizione. Vedere "Shared ObjectDependencies" di seguito per ulteriori informazioni su questi nomi.
Quindi ora, quando viene creato un eseguibile, SONAME è incorporato in esso. Quando quando viene eseguito l'eseguibile viene utilizzato dal linker per cercare la libreria nei file nelle posizioni predefinite per la libreria dinamica. La posizione predefinita in Windows sarebbe ovunque risiedano le DLL. In Linux e Mac OS X e altri sistemi compatibili con System V sarebbero /lib
e /usr/lib
e possibilmente altri punti, dipende dal linker utilizzato e può essere definito nelle configurazioni dei linker.
In ogni caso il linker cerca di vedere se la libreria nominata nella voce soname è presente in una qualsiasi di quelle posizioni, se lo è la userà.
Nota che lo standard dice che il soname è una STRINGA e le convenzioni di versioning sono diventate uno standard de facto dopo il fatto e sono qualcosa del genere:
Fai in modo che il soname sia libmyname.so.A
e fai in modo che il nome file della libreria sia libmyname.so.A.B o libmyname.so.A.B.C (sotto MacOSX è libmyname.A.B.dylib). Crea un softlink da libmyname.so.A.B[.C]?
a libmyname.so.A
.
A
viene mantenuto lo stesso mentre l'ABI della biblioteca rimane lo stesso.
B
(o B.C
) diventa la versione secondaria.
Sotto Linux è molto comune che la versione della libreria sia la stessa del numero di versione del pacchetto. Questo ha i suoi pro e contro.
formalizzazione libtool
GNU libtool è usato molto per costruire librerie dinamiche, ha un sistema di controllo delle versioni più formale e ha una forte logica per questo. Il sistema di versioning libtool per sonames funziona molto bene ed è adottato da librerie complesse per mantenere le cose in ordine.
Sotto libtool, il versioning è come sotto:
libmylib-corrente .rilascio .età
Sotto libtool l'idea è che man mano che le librerie si evolvono aggiungeranno e rimuoveranno funzionalità.
Diciamo che stai sviluppando una libreria. Inizia usando una versione come 0.0.0
.
Ora supponiamo che correggi alcuni bug, aumenteresti solo il rilascio numero.
Quindi il nuovo nome sarebbe libmylib.0.1.0 o libmylib.0.2.0 ecc.. per ogni versione che corregge solo bug ma non cambia nulla dell'ABI.
Lungo la strada dici. Uffa! Avrei potuto fare meglio questa sottofunzionalità, quindi aggiungi un nuovo set di funzioni per fare qualcosa di meglio, ma poiché altri stanno ancora usando la tua libreria, lasci comunque la vecchia funzionalità (obsoleta).
Le regole sono come sotto:
Inizia con le informazioni sulla versione di "0:0:0" per ogni libreria libtool.
Aggiornare le informazioni sulla versione solo immediatamente prima di un rilascio pubblico del software. Aggiornamenti più frequenti non sono necessari e garantiscono solo che il numero di interfaccia corrente aumenti più velocemente.
Se il codice sorgente della libreria è cambiato dall'ultimo aggiornamento, incrementa la revisione ('c:r:a' diventa 'c:r+1:a').
Se sono state aggiunte, rimosse o modificate interfacce dall'ultimo aggiornamento, incrementa la corrente e imposta la revisione su 0.
Se sono state aggiunte interfacce dall'ultima versione pubblica, incrementa l'età.
Se sono state rimosse o modificate delle interfacce dall'ultima versione pubblica, imposta l'età su 0.
Puoi leggere di più a riguardo nella documentazione di libtool
Aggiorna ...
Quello che segue è stato un commento che la mia spiegazione ha un errore. Non è necessario, il che richiede un po' più di dettagli di quelli che possono essere inseriti in un commento di risposta, quindi vedi sotto.
Obiezione originale
C'è un errore qui:su Linux, la versione è di formlibmylib.(current-age).release.age, dove le parentesi indicano un'espressione da valutare. Ad esempio GLPK 4.54 withcurrent:revision:age =37:1:1 su Linux installa la libreria filelibglpk.so.36.1.1. Per maggiori informazioni, vedi, ad esempio,
.
Confutazione
TLDR:fonte non autorevole di autotools.io.SpiegazioneAnche se Flameeyes è uno sviluppatore straordinario ed è uno dei manutentori di Gentoo, è stato lui che ha commesso l'errore e ha creato una "regola empirica" libera interpretazione della specifica libtool. Anche se questo non interromperà i sistemi il 99% delle volte, se dovessimo seguire il modo ad hoc di aggiornare corrente :
Le regole empiriche, quando si ha a che fare con questi valori sono:
Aumenta sempre il valore di revisione.
Aumenta il valore corrente ogni volta che un'interfaccia è stata aggiunta, rimossa o modificata.
Aumentare il valore dell'età solo se le modifiche apportate all'ABI sono compatibili con le versioni precedenti.
poi prosegue dicendo che mantenendo più versioni di Gtk sarebbe meglio aggiungere semplicemente la versione della libreria nel NOME della libreria e semplicemente scaricare il numero di versione. (come fanno in GTK+):
In questa situazione, l'opzione migliore è aggiungere parte delle informazioni sulla versione della libreria al nome della libreria, che è esemplificato dal soname libglib-2.0.so.0 di Glib. Per fare ciò, la dichiarazione in theMakefile.am deve essere così:
lib_LTLIBRARIES = libtest-1.0.la libtest_1_0_la_LDFLAGS = -version-info 0:0:0
Bene, questo è solo un approccio crockpot per confondere il potere del collegamento dinamico e del controllo delle versioni della risoluzione dei simboli completamente discutibile !. Sta dicendo di spegnerlo. Caccole di cavalli! Non c'è da stupirsi che anche gli sviluppatori esperti abbiano avuto difficoltà a creare e mantenere progetti open source e ci imbattiamo costantemente in file binari che muoiono ogni volta che vengono installate nuove versioni di librerie (perché si intasano a vicenda).
L'approccio al versioning di libtool è MOLTO BEN PENSATO . È un algoritmo e i suoi passaggi sono ordinati istruzioni 1 a 6 devono essere seguiti ogni volta che c'è un aggiornamento al codice di una libreria collegata dinamica.
Per gli sviluppatori nuovi e attuali, si prega di leggerli attentamente e visualizzare cosa accadrà al numero di versione della libreria per tutta la vita del proprio fantastico software. Se lo fai noterai che ogni pezzo di software precedentemente collegato utilizzerà sempre correttamente la versione più aggiornata e accurata della tua fantastica libreria e nessuna di esse si urteranno o calpesteranno mai l'un l'altro, E non devi mai aggiungere un numero fiorente nel nome della tua libreria (a meno che non sia per piacere o estetica).