Numéros de version dans les fichiers objects partagés

Je construis un fichier object partagé à partir d’un groupe de fichiers source C ++ utilisant GCC. Tous les exemples de tutoriels sur la création de fichiers .so montrent le fichier créé avec un numéro de version après le suffixe .so . Par exemple:

 gcc -shared -Wl,-soname,libmean.so.1 -o libmean.so.1.0.1 calc_mean.o 

Cela produirait le fichier .so libmean.so.1.0.1

De plus, si je navigue dans le /usr/lib sur mon /usr/lib local, je constate que la plupart des fichiers .so ont des numéros de version à la fin.

Cependant, lorsque je comstack un fichier object partagé et le place dans /usr/lib , l’éditeur de liens ne peut pas le trouver si je mets un numéro de version à la fin. Si je supprime le numéro de version, cela fonctionne bien. Je ne me soucie pas vraiment de mettre un numéro de version ou pas, je ne comprends tout simplement pas pourquoi cela semble être une convention courante, et pourtant, la bibliothèque partagée ne fonctionne pas avec l’éditeur de liens. Alors, qu’est-ce qui se passe ici? Pourquoi existe-t-il une convention pour placer le numéro de version à la fin d’un nom de fichier .so ?

Le numéro de version est ajouté afin que plusieurs versions de bibliothèque incompatibles puissent coexister dans le système. Vous devez incrémenter le numéro de version majeur (le numéro dans le soname ) chaque fois que vous modifiez l’API de manière incompatible (en supposant que la version précédente est installée et utilisée dans le système, bien sûr).

Les 2ème et 3ème numéros du nom du fichier permettent plusieurs révisions mineures de la bibliothèque du système, commutables à l’échelle du système avec une simple mise à jour du lien symbolique.

Au moment du lien, vous pouvez donner le nom du fichier .so tant qu’argument de l’éditeur de liens, au lieu de l’option -l . ldd est assez intelligent pour en extraire le soname , le binary ainsi lié l’utilise pour trouver la bibliothèque.

Par exemple, compilons la bibliothèque et testons le binary en l’utilisant:

 czajnik@czajnik:~/z$ gcc -shared -Wl,-soname,libtest.so.2 -o libtest.so.2.3.4 ac czajnik@czajnik:~/z$ gcc -o test bc -L. ./libtest.so.2.3.4 

Vous pouvez utiliser ldd pour vérifier que le binary recherche maintenant libtest.so.2 :

 czajnik@czajnik:~/z$ LD_LIBRARY_PATH=. ldd ./test linux-gate.so.1 => (0x002c1000) libtest.so.2 => not found libc.so.6 => /lib/libc.so.6 (0x00446000) /lib/ld-linux.so.2 (0x00a28000) 

Il ne peut évidemment pas le trouver, mais c’est à quoi sert le lien symbolique:

 czajnik@czajnik:~/z$ ln -s libtest.so.2.3.4 libtest.so.2 czajnik@czajnik:~/z$ LD_LIBRARY_PATH=. ldd ./test linux-gate.so.1 => (0x00d75000) libtest.so.2 => ./libtest.so.2 (0x00e31000) libc.so.6 => /lib/libc.so.6 (0x00a5e000) /lib/ld-linux.so.2 (0x00378000) 

Mise à jour: Tout ce qui précède est vrai, mais je n’étais pas au courant de la signification du 3ème composant du numéro de version. Jusqu’à récemment, je pensais que c’était simplement un numéro de patch (ou une chose similaire). Faux! Pour libtool, cela a une signification particulière.

Le troisième composant s’est avéré être le champ age , qui indique combien de versions majeures sont rétrocompatibles avec la version actuelle .

Lecture recommandée:

  • Idiot’s Guide to ABI Versioning
  • Le système de gestion des versions de Libtool