Habituellement, lorsque vous construisez des objets partagés (.so), vous vous occupez également des versions en ajoutant des suffixes tels que mylib.so.2.3.1. Pour vous assurer que vos programmes peuvent charger cette bibliothèque ou d'autres versions ultérieures, vous créez des liens avec des noms
mylib.so -> mylib.so.2.3.1
mylib.so.2 -> mylib.so.2.3.1
mylib.so.2.3 -> mylib.so.2.3.1
Ainsi, tout ce qui suit .so représente version.sub-version.build (ou similaire) De plus, il est possible que plusieurs versions de la même bibliothèque coexistent avec ce schéma, et tout ce qui est nécessaire pour basculer les programmes vers une utilisation particulière version est d'avoir les liens appropriés en place.
Le binaire ELF lié dynamiquement (qu'il s'agisse d'une autre bibliothèque ou d'un exécutable) utilise un nom d'objet partagé ou soname pour identifier la bibliothèque à laquelle l'exécutable doit être lié lors de l'exécution.
Lorsqu'une bibliothèque est créée en tant que bibliothèque partagée ELF, l'éditeur de liens au moment de la compilation insère un champ DT_SONAME dans l'exécutable qui contient le SONAME de la bibliothèque dans la bibliothèque elle-même. Le DT_SONAME est défini dans la norme ELF comme :
Cet élément contient l'offset de table de chaînes d'une chaîne à terminaison nulle, donnant le nom de l'objet partagé. L'offset est un index dans la table enregistré dans le
DT_STRTAB
entrée. Voir ‘‘Shared Object Dependencies’’ ci-dessous pour plus d'informations sur ces noms.
Alors maintenant, lorsqu'un exécutable est créé, le SONAME y est intégré. Quand l'exécutable est exécuté est utilisé par l'éditeur de liens pour rechercher la bibliothèque dans les fichiers dans les emplacements prédéfinis pour la bibliothèque dynamique. L'emplacement prédéfini dans Windows serait là où résident les DLL. Sous Linux et Mac OS X et d'autres systèmes compatibles System V, ils seraient /lib
et /usr/lib
et éventuellement d'autres spots, cela dépend du linker utilisé, et peut être défini dans les propres configurations des linkers.
Dans tous les cas, l'éditeur de liens vérifie si la bibliothèque nommée dans l'entrée soname est présente à l'un de ces emplacements, si c'est le cas, il l'utilisera.
Notez que la norme indique que le soname est une CHAÎNE et que les conventions de version sont devenues une norme de facto après coup et ressemblent à ceci :
Faites en sorte que le soname soit libmyname.so.A
et faites en sorte que le nom de fichier de la bibliothèque soit libmyname.so.A.B ou libmyname.so.A.B.C (sous MacOSX, c'est libmyname.A.B.dylib). Créer un lien symbolique à partir de libmyname.so.A.B[.C]?
à libmyname.so.A
.
A
reste le même tandis que l'ABI de la bibliothèque reste le même.
B
(ou B.C
) devient la version mineure.
Sous Linux, il est très courant que la version de la bibliothèque soit la même que le numéro de version du package. Cela a ses avantages et ses inconvénients.
formalisation de libtool
GNU libtool est beaucoup utilisé pour créer des bibliothèques dynamiques, et dispose d'un système de gestion des versions plus formel et d'une logique forte pour cela. Le système de gestion des versions de libtool pour sonames fonctionne très bien et est adopté par des bibliothèques complexes pour garder les choses en ordre.
Sous libtool, le versioning est le suivant :
libmylib-current .libérer .âge
Sous libtool, l'idée est qu'au fur et à mesure que les bibliothèques évoluent, elles ajouteront et supprimeront des fonctionnalités.
Disons que vous développez une bibliothèque. Commencez par utiliser une version comme 0.0.0
.
Supposons maintenant que vous corrigiez quelques bogues, vous ne feriez qu'augmenter la version numéro.
Ainsi, le nouveau nom serait libmylib.0.1.0 ou libmylib.0.2.0 etc. pour chaque version qui corrige juste des bogues mais ne change rien à l'ABI.
En chemin tu dis. Pouah! J'aurais pu mieux faire cette sous-fonctionnalité, vous ajoutez donc un nouvel ensemble de fonctions pour faire quelque chose de mieux, mais parce que d'autres utilisent toujours votre bibliothèque, vous laissez toujours l'ancienne fonctionnalité (obsolète).
Les règles sont les suivantes :
Commencez avec les informations de version "0:0:0" pour chaque bibliothèque libtool.
Ne mettez à jour les informations de version qu'immédiatement avant une version publique de votre logiciel. Des mises à jour plus fréquentes sont inutiles et garantissent uniquement que le numéro d'interface actuel augmente plus rapidement.
Si le code source de la bibliothèque a changé depuis la dernière mise à jour, alors incrémentez la révision ("c:r:a" devient "c:r+1:a").
Si des interfaces ont été ajoutées, supprimées ou modifiées depuis la dernière mise à jour, incrémentez current et définissez revision sur 0.
Si des interfaces ont été ajoutées depuis la dernière version publique, incrémentez l'âge.
Si des interfaces ont été supprimées ou modifiées depuis la dernière version publique, définissez l'âge sur 0.
Vous pouvez en savoir plus à ce sujet dans la documentation de libtool
Mettre à jour...
Ce qui suit était un commentaire que mon explication a une erreur. Ce n'est pas le cas, ce qui nécessite un peu plus de détails que ce qui peut être mis dans un commentaire de réponse, alors voir ci-dessous.
Objection initiale
Il y a une erreur ici :sous linux, la version est de la forme libmylib.(current-age).release.age, où les parenthèses indiquent une expression à évaluer. Par exemple, GLPK 4.54 withcurrent:revision:age =37:1:1 sur Linux installe la bibliothèque filelibglpk.so.36.1.1. Pour plus d'informations, voir, par exemple,
.
Réfutation
TLDR :autotools.io n'est pas une source faisant autorité. ExplicationAlors que Flameeyes est un développeur incroyable et qu'il est l'un des mainteneurs de Gentoo, c'était il qui a fait l'erreur et a créé une interprétation lâche de la "règle générale" de la spécification libtool. Bien que cela ne va pas casser les systèmes 99 % du temps, si nous devions suivre la méthode ad hoc de mise à jour current :
Les règles de base, lorsqu'il s'agit de ces valeurs sont :
Augmentez toujours la valeur de révision.
Augmentez la valeur actuelle chaque fois qu'une interface a été ajoutée, supprimée ou modifiée.
Augmentez la valeur d'âge uniquement si les modifications apportées à l'ABI sont rétrocompatibles.
il poursuit en disant que pour maintenir plusieurs versions de Gtk, il serait préférable d'ajouter simplement la version de la bibliothèque dans le NOM de la bibliothèque et de simplement vider le numéro de version. (comme ils le font dans GTK+) :
Dans cette situation, la meilleure option consiste à ajouter une partie des informations de version de la bibliothèque au nom de la bibliothèque, ce qui est illustré par le soname libglib-2.0.so.0 de Glib. Pour ce faire, la déclaration dans theMakefile.am doit ressembler à ceci :
lib_LTLIBRARIES = libtest-1.0.la libtest_1_0_la_LDFLAGS = -version-info 0:0:0
Eh bien, c'est juste une approche mijoteuse pour gâcher la puissance de la liaison dynamique et du versionnage de la résolution des symboles complètement sans objet !. Il dit qu'il suffit de l'éteindre. Crottes de cheval ! Pas étonnant que même les développeurs expérimentés aient eu du mal à créer et à maintenir des projets open source et que nous rencontrions constamment des fichiers binaires qui meurent chaque fois que de nouvelles versions de bibliothèques sont installées (parce qu'elles s'écrasent les unes les autres).
L'approche de gestion des versions de libtool est TRÈS BIEN PENSÉE . C'est un algorithme et ses étapes sont ordonnées mode d'emploi 1 à 6 doivent être suivies chaque fois qu'il y a une mise à jour du code d'une bibliothèque liée dynamiquement.
Pour les développeurs nouveaux et actuels, veuillez les lire attentivement et visualiser ce qui arrivera au numéro de version de la bibliothèque tout au long de la vie de votre incroyable logiciel. Si vous le faites, vous remarquerez que chaque logiciel précédemment lié utilisera toujours correctement la version la plus récente et la plus précise de votre incroyable bibliothèque, et aucune d'entre elles vont jamais se cogner ou se piétiner, ET vous n'êtes jamais obligé d'ajouter un numéro fleuri au nom de votre bibliothèque (sauf si c'est pour le plaisir ou l'esthétique).