Rappel :

Lorsque l'ABI est stable, un logiciel compilé avec la version N d'une bibliothèque continuera de fonctionner avec la version N+1. C'est ce qui permet d'assurer les mises à jour sans devoir reconstruire de nombreux paquets.

Par exemple, lorsqu'un programme utilise le client MySQL, il demande la liaison avec libmysqlclient.so. En réalité il utilisera, la bibliothèque libmysqlclient.so.16. Cette version "16" (soname) sera la même pour toutes les versions fournies avec MySQL 5.1. (MySQL 5.0 fournissait libmysqlclient.so.15). La statibilité de l'ABI est donc garantie. RPM assure ce contrôle à l'aide des dépendances sur le nom avec version des bibliohèques utilisées.

$ rpm -q --provides mysql-libs
libmysqlclient.so.16()(64bit) 
libmysqlclient_r.so.16()(64bit)
...
$ rpm -q --requires mysql++
libc.so.6()(64bit) 
libgcc_s.so.1()(64bit) 
libm.so.6()(64bit) 
libmysqlclient_r.so.16()(64bit) 
libmysqlpp.so.3()(64bit) 
libpthread.so.0()(64bit) 
...

Normalement, c'est aux développeurs de s'assurer, en amont, de cette stabilité. Lorsqu'un changement est nécessaire, il faut changer le numéro de version de la bibliothèque (qui n'a souvent aucun rapport avec la version des sources). Le mainteneur du paquet devra alors reconstruire tous les logiciels qui l'utilisent (ou fournir une bibliothèque de compatibilité).

Bien entendu, c'est une bonne pratique, pour un mainteneur de paquets de s'assuré de cette stabilité avant de mettre à jour la distribution.

Exemple :

A l'occasion de la sortie de la version 3.1.0 de mysql++, j'ai réalisé ce contrôle et décidé de publier ce billet, principalement pour conserver des notes sur la méthode utilisée, et pour en faire profiter ceux qui s'interrogent sur les moyens disponibles.

J'ai utilisé un outil simple et libre : ABI compliance checker ainsi que le test trivial d'utilisation d'une application.

Avec la version 3.0.9

Construire les exemples (en supprimant le test de version prévu dans le code)

$ su -lc "yum install mysql++-devel"
$ cp -r /usr/share/doc/mysql++-devel-3.0.9/examples /tmp/ex309
$ cd /tmp/ex309
$ vi resetdb.cpp # virer le return 1 après le test de version
$ make

Installer l'outil et lancer l'analyse pour la version 3.0.9

$ wget http://ispras.linux-foundation.org/images/6/6e/Abi-compliance-checker-1.17.2.tar.gz
$ tar xzf Abi-compliance-checker-1.17.2.tar.gz
$ cd abi-compliance-checker-1.17.2
$ ./abi-compliance-checker.pl -d
$ mv lib_ver.xml my309.xml
$ gedit mysql++309.xml
$ abi-compliance-checker -l mysql++ -dump_abi mysql++309.xml

Le fichier  mysql++309.xml décrivant le bibliothèque est très simple

<?xml version="1.0" encoding="UTF-8"?>
<descriptor>
<version>
3.0.9
</version>
<headers>
/usr/include/mysql++/
</headers>
<libs>
/usr/lib64/libmysqlpp.so
</libs>
<include_paths>
/usr/include/mysql
</include_paths>
...

Le fichier résultat sera nécessaire plus tard.

Avec la version 3.1.0

Mettre à jour. Les exemples doivent toujours fonctionner

$ su -lc "rpm -Uvh mysql++*3.1.0*"
$ cd /tmp/ex309
$ ./simple1 -u toto -p secret
We have:
    Nuerenberger Bratwurst
    Pickle Relish
    Hot Mustard
    Hotdog Buns
    Hot Dogs
$ ./cpool -u toto -p secret
Segmentation fault (core dumped)

Visiblement, il y a un problème.

Lancer l'analyse

$ cp mysql++309.xml mysql++310.xml
$ gedit mysql++310.xml
$ abi-compliance-checker -l mysql++ -dump_abi mysql++310.xml

Lancer la comparaison des 2 résultats.

$ ./abi-compliance-checker.pl -l mysql++ \
-d1 abi_dumps/mysql++/mysql++_3.0.9.abi.tar.gz \
-d2 abi_dumps/mysql++/mysql++_3.1.0.abi.tar.gz
$ firefox file:$PWD/compat_reports/mysql++/3.0.9_to_3.1.0/abi_compat_report.html

Voir le résultat : ABI compliance report for the library mysql++ from version 3.0.9 to 3.1.0 on x86_64

Dans ce cas nous avons bien confirmation de l'incompatibilité entre les 2 versions. Donc la mise à jour dans les dépôts stables ne sera pas proposée.

Bilan :

Bien évidement ce problème doit être signalé aux développeurs du projet et aux autres mainteneurs de paquets.

A l'origine, lorsque j'ai commencé la maintenance de ce paquet (version 2.x), la bibliothèque n'était même pas versionnée. Il a donc fallu discuter avec les développeurs pour que cela soit ajouté. Maintenant, il faut les convaincre de respecter les usages.