[OpenBSD]

Comment gérer les bibliothèques partagées dans l'arbre des ports

Comprendre les règles de numérotation des bibliothèques partagées

Les bibliothèques partagées sont quelque peu rusées et ce pour plusieurs raisons. Vous devez comprendre le schéma de nommage des bibliothèques : libfoo.so.majeur.mineur.

Quand vous liez un programme, l'éditeur de liens ld inclut cette information dans le binaire créé. Vous pouvez voir ceci avec ldd. Par la suite, lorsque vous lancez le programme, l'éditeur de liens dynamique ld.so utilise cette information pour trouver la bonne bibliothèque dynamique :

Ainsi, cela signifie que toutes les bibliothèques avec le même numéro majeur et un numéro mineur égal ou supérieur doivent satisfaire l'API binaire que le programme prévoit. Si ce n'est pas le cas, votre port est alors cassé. Spécifiquement, cela se produira quand les utilisateurs essaieront de mettre à jour leurs systèmes.

Les règles pour les bibliothèques partagées sont relativement simples.

Parfois, il arrive qu'une bibliothèque soit écrite en plusieurs fichiers, et que les fonctions internes doivent apparaitre comme visibles pour communiquer avec ces fichiers. Ces noms de fonction commencent traditionnellement avec un trait de soulignement, et ne sont pas une partie proprement dite de l'API.

Notez que le schéma de nommage des bibliothèques est omniprésent sur les plates-formes OpenBSD qu'elles soient ELF ou a.out.

Peaufiner les constructions de ports pour obtenir les noms corrects

Un certain nombre de ports ont besoin d'être peaufinés afin de compiler correctement et continuellement les bibliothèques partagées. Rappelez vous que la construction des bibliothèques partagées doit être réalisée avec gcc -shared -fpic|-fPIC -o libfoo.so.4.5 obj1 obj2

Renommez la bibliothèque après ceci afin d'ajuster le numéro de version ne marche pas : les bibliothèques ELF utilisent d'autres nombres magiques pour fixer le nom interne de la bibliothèque, et vous devriez ainsi la lier avec une version correcte dès la première fois.

D'un autre côté, rappelez vous que vous pouvez redéfinir les variables du Makefile depuis la ligne de commande, en utilisant MAKE_FLAGS dans le Makefile du port. Ceci est tout à fait utile pour les ports basés sur la libtool par exemple, qui fournissent une version variable pour chaque bibliothèque qu'ils créent.

Le meilleur moyen de gérer les ports basés sur libtool est d'utiliser la variable USE_LIBTOOL=Yes. Cela active la version de libtool présente dans l'arbre des ports qui se charge automatiquement de la plupart des détails :

Essayer de placer toutes les bibliothèques visibles à un utilisateur dans /usr/local/lib

En règle générale, demander à l'utilisateur d'ajouter des répertoires dans leur "path" ldconfig est une très mauvaise idée : toutes les bibliothèques partagées qui sont directement liées aux programmes devraient apparaitre dans /usr/local/lib. Cependant, il est tout à fait possible d'utiliser un lien symbolique vers la bibliothèque actuelle. Vous devriez comprendre les règles de parcour des bibliothèques : A présent, supposons que vous avez deux ports qui fournissent deux versions majeures d'une bibliothèque donnée, à savoir qt.1.45 et qt.2.31. Puisque les deux ports peuvent être installés simultanément, pour être sur qu'un programme donné sera lié avec qt.1, cette bibliothèque est fournie avec /usr/local/lib/qt/libqt.so.1.45, et les programmes seront liés en utilisant ld -o program program.o -L/usr/local/lib/qt -lqt. De même, un programme lié avec qt.2 utilisera le fichier /usr/local/lib/qt2/libqt.so.2.31 avec ld -o program program.o -L/usr/local/lib/qt2 -lqt.

Pour résoudre ces bibliothèques au moment du lancement, un lien appelé /usr/local/lib/libqt.so.1.45 et un lien appelé /usr/local/lib/libqt.so.2.31 sont fournis. Ceci est suffisant pour satisfaire ld.so

Lier un programme en utilisant qt1 avec ld -o program program.o -L/usr/local/lib -lqt est une erreur. Ce code suppose que le qt.2.31 n'est pas installé, ce qui est une fausse prétention.

De telles astuces sont uniquement nécessaires dans les rares cas de bibliothèques dominantes ou une période de transition entre deux versions majeures doit être fournie. En général, ceci est suffisant pour s'assurer de la présence de la bibliothèque dans /usr/local/lib.

Ecrire correctement les dépendances de bibliothèque

Le nouveau code de dépendance a besoin des dépendances complètes des bibliothèques. Vous devez utiliser make lib-depends-check ou make port-lib-depends-check pour vérifier qu'un port mentionne toutes les bibliothèques requises. Vous devez juste les écrite dans LIB_DEPENDS/WANTLIB comme cela :
        LIB_DEPENDS += ::x11/gtk+
        WANTLIB += gtk.>=1.2,gdk.>=1.2

Spécifier les bibliothèques statiques sur la ligne WANTLIB n'est pas une erreur à part entière. WANTLIB est évaluée intégralement au moment de la construction du paquet : le paquetage résultant aura une information de dépendance de bibliothèque inclut dans ld.so qui porte le numéro majeur.mineur actuel qui était utilisé pour la construction, mais rien pour les bibliothèques statiques.

Vous devez aussi fournir RUN_DEPENDS si un port requiert quelquechose au delà d'une bibliothèque proprement dite. Ceci permettra au port de se construire correctement sur les architectures qui ne supportent pas les bibliothèques partagées.

En fait, fournir les lignes LIB_DEPENDS même pour les bibliothèques statiques est une bonne idée : ceci simplifiera la mise à jour du port si une dépendance donnée passe d'une bibliothèque statique à une bibliothèque partagée.

Les lignes WANTLIB doivent spécifier les même "paths" que ceux utilisés par ld. Avec le même exemple que précedemment, le fragment qt2 standard dit WANTLIB += lib/qt2/qt.=2. Ceci permet au code de vérification des bibliothèques de faire le bon choix quand plusieurs versions de la même bibliothèque sont découvertes.

Mettre à jour les ports correctement

Ainsi, quand vous mettez à jour ou ajoutez un port qui implique des bibliothèques partagées, quelques détails doivent être respectés.
OpenBSD www@openbsd.org
$OpenBSD: libraries.html,v 1.9 2011/08/25 12:13:09 ajacoutot Exp $