[ précédent ] [ Table des matières ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ 11 ] [ 12 ] [ A ] [ B ] [ C ] [ D ] [ E ] [ F ] [ G ] [ suivant ]


La Charte Debian
Chapitre 8 - Les bibliothèques partagées


On doit construire avec soin les paquets qui contiennent des bibliothèques partagées afin de s'assurer que ces bibliothèques seront toujours disponibles. Et particulièrement, les paquets qui demandent des bibliothèques vitales, telle que la bibliothèque C, (actuellement : libc6).

Un paquet qui contient des bibliothèques partagées sera séparé en plusieurs paquets binaires. Cette section est consacrée à la façon de faire cette séparation ; les règles pour les fichiers à l'intérieur des paquets de bibliothèques partagées sont traitées dans Les bibliothèques, Section 10.2.


8.1 Les bibliothèques reliables dynamiquement

La bibliothèque partagée doit être placée dans un paquet dont le nom change chaque fois que la version objet partagée change. [45] Le mécanisme le plus courant est de mettre la bibliothèque dans un paquet appelé nom-de-bibliothèqueversion-so, où version-so est le numéro de version du nom-so de la bibliothèque partagée [46] Quand cela amène de la confusion d'ajouter directement version-so à nom-de-bibliothèque (par exemple, quand nom-de-bibliothèque se termine lui-même par un numéro), on peut aussi utiliser à la place nom-de-bibliothèque-version-so et nom-de-bibliothèque-version-so-dev.

Si votre paquet comprend des programmes d'aide exécutables que les utilisateurs n'ont pas besoin d'appeler eux-mêmes, mais qui sont néammoins nécessaires au fonctionnement du paquet, il est recommandé de placer ces programmes (si ce sont des binaires) dans un répertoire de /usr/lib, de préférence sous /usr/lib/nom-de-paquet. Si les programmes ne dépendent pas de l'architecture, il est recommandé de les placer dans un répertoire de /usr/share, de préférence sous /usr/share/nom-de-paquet.

Si vous construisez plusieurs bibliothèques partagées à partir d'un même arbre de sources, vous pouvez les regrouper dans le même paquet de bibliothèques, sachant que vous devrez changer tous leurs nom-so simultanément (pour éviter des conflits de noms de fichiers lors de l'installation de différentes versions de ce paquet).

Une paquet installera les bibliothèques partagées sous leurs vrais noms. Par exemple, le paquet libgdbm3 installera libgdbm.so.3.0.0 en tant que /usr/lib/libgdbm.so.3.0.0. Aucun script prerm ou postrm ne changera le nom de ces fichiers ni ne créera de lien pour ces fichiers ; dpkg s'occupe des changements de nom et cela, sans troubler les programmes en fonctionnement. Essayer d'interférer avec ce système crée des problèmes.

Les bibliothèques partagées ne doivent pas être installées comme exécutables, puisque l'éditeur de liens dynamiques ne le demande pas et que tenter d'exécuter une bibliothèque partagée se traduit par un core dump.

Le paquet de la bibliothèque partagée comportera le lien symbolique que ldconfig voudra créer pour les bibliothèques partagées. Par exemple, le paquet libgdbm3 inclura un lien symbolique de /usr/lib/libgdbm.so.3 vers libgdbm.so.3.0.0. C'est nécessaire pour que l'éditeur des liens dynamiques (ld.so ou ld-linux.so.*) puisse trouver la bibliothèque entre le moment où dpkg l'installe et celui où ldconfig est exécuté par le script postinst [47].


8.1.1 ldconfig

Tout paquet qui installe des bibliothèques partagées dans l'un des répertoires par défaut de l'éditeur de liens dynamiques, (actuellement, /usr/lib et /lib) ou dans un répertoire listé par /etc/ld.so.conf [48] doit utiliser ldconfig pour mettre à jour le système des bibliothèques partagées.

Les scripts de responsable de paquet ne doivent appeler ldconfig que dans ces circonstances :

[49].


8.2 Les programmes d'aide au fonctionnement

Si votre paquet contient des programmes d'aide au fonctionnement qui utilisent la bibliothèque partagée, vous ne devez pas les mettre dans le paquet de la bibliothèque partagée. Si vous le faites, vous ne pourrez pas installer plusieurs versions de la bibliothèque sans créer des conflits de noms de fichiers.

À la place, vous pouvez soit créer un autre paquet pour ces binaires fonctionnels (le paquet peut s'appeler nom-de-bibliothèque-runtime -- notez l'absence de version-so dans le nom du paquet), soit inclure ces binaires dans le paquet de développement si celui-ci est petit.


8.3 Les bibliothèques statiques

Une bibliothèque statique (nom-de-bibliothèque.a) accompagne généralement la version partagée ; elle est placée dans le paquet de développement. Voyez plus bas.

Dans les cas suivants, il est acceptable qu'une bibliothèque ne soit disponible que sous sa forme statique :


8.4 Les fichiers de développement

Les fichiers de développement associés à une bibliothèque partagée seront placés dans un paquet appelé nom-de-bibliothèqueversion-so-dev, ou, si vous préférez ne gérer qu'une version de développement à la fois, nom-de-bibliothèque-dev.

Quand plusieurs versions de développement existent, vous pouvez utiliser le mécanisme de gestion des conflits de dpkg (voir Mettre en conflit des paquets binaires -- le champ Conflicts, Section 7.3) pour vous assurer que l'utilisateur ne peut installer qu'une seule version de développement à la fois. Plusieurs versions de développement auront sans doute les mêmes fichiers d'en-tête, ce qui créera un conflit de nom en cas d'installation multiple.

Le paquet de développement contiendra un lien symbolique vers la bibliothèque partagé qui lui est associée sans le numéro de version. Par exemple, le paquet libgdbm-dev fera un lien de /usr/lib/libgdbm.so vers libgdbm.so.3.0.0. L'éditeur de liens (ld) a besoin de ce lien pour la compilation des programmes car il ne recherche que libgdbm.so lors d'une compilation dynamique.


8.5 Les dépendances entre les paquets d'une même bibliothèque

La version de développement aura une dépendance sur une version précise de la bibliothèque partagée afin que la compilation et l'édition de liens s'effectuent correctement. La variable de substitution ${Source-Version} peut être utile dans ce cas.


8.6 Les dépendances entre une bibliothèque et les paquets - le système shlibs

Quand un paquet contient un binaire ou une bibliothèque liés à une bibliothèque partagée, on doit s'assurer que, lors de l'installation de ce paquet sur le système, toutes les bibliothèques nécessaires sont aussi installées. Cela a conduit à la création du système shlibs ; de conception très simple, ce système demande que tout paquet qui fournit (champ provides) une bibliothèque partagée donne aussi les informations de dépendance nécessaires à la présence de cette bibliothèque ; ainsi tout paquet qui utilise une bibliothèque partagée, utilise ces informations pour connaître les dépendances requises. Les fichiers qui contiennent les relations entre les bibliothèques partagées et les informations sur les dépendances nécessaires sont les fichiers shlibs.

Ainsi, quand on construit un paquet contenant une bibliothèque partagée, on doit fournir un fichier shlibs utilisable par d'autres paquets ; et quand on construit un paquet contenant une bibliothèque partagée ou un binaire compilé, ce paquet doit exécuter dpkg-shlibdeps pour ces programmes de manière à connaître les bibliothèques utilisées et donc les dépendances nécessaires à ce paquet [50].

Les sections suivantes décrivent l'emplacement des différents fichiers shlibs, la façon d'utiliser le programme dpkg-shlibdeps, et le format du fichier shlibs ainsi que la façon de créer ces fichiers quand un paquet contient une bibliothèque partagée.


8.6.1 Les fichiers shlibs sur le système

On peut trouver des fichiers shlibs à plusieurs endroits. La liste suivante les donne dans l'ordre selon lequel dpkg-shlibdeps les a lus. Le premier qui donne l'information demandée est utilisé.


8.6.2 Comment utiliser dpkg-shlibdeps et les fichiers shlibs ?

Placez un appel au programme dpkg-shlibdeps dans le fichier debian/rules. Si le paquet contient seulement des binaires compilés et des bibliothèques (mais pas de scripts), on peut utiliser la commande :

     dpkg-shlibdeps debian/tmp/usr/bin/* debian/tmp/usr/sbin/* \
       debian/tmp/usr/lib/*

Sinon, on devra explicitement lister les binaires compilés et les bibliothèques [52].

Cette commande place les informations sur les dépendances dans le fichier debian/substvars, qui est ensuite utilisé par dpkg-gencontrol. Vous devrez placer une variable ${shlibs:Depends} dans le champ Depends du fichier de contrôle pour que cela marche.

Si dpkg-shlibdeps ne se plaint pas, c'est bon. Sinon, vous pourriez avoir besoin de créer un fichier debian/shlibs.local, comme expliqué plus bas (Comment écrire le fichier debian/shlibs.local ?, Section 8.6.5).

Si vous avez des paquets contenant plusieurs binaires, vous devrez appeler dpkg-shlibdeps sur tous ceux qui ont des binaires compilés et des bibliothèques. Dans ce cas, vous aurez besoin de l'option -T des outils dpkg pour spécifier un fichier substvars différent.

Veuillez consulter dpkg-shlibdeps - les dépendances des bibliothèques partagées, Section C.1.4 et dpkg-shlibdeps(1) pour des précisions sur le programme dpkg-shlibdeps.


8.6.3 Le format du fichier shlibs

Chaque fichier shlibs possède le même format. Les lignes commençant par # sont des commentaires et sont ignorées. Chaque ligne est de la forme :

     nom-de-bibliothèque nomso-version-numéro dépendances ...\

Nous allons expliquer cette ligne en prenant comme exemple le paquet zlib1g, qui, au moment où est écrit ce texte, installe la bibliothèque partagée /usr/lib/libz.so.1.1.3.

nom-de-bibliothèque est le nom de la bibliothèque partagée, dans ce cas : libz. Cela doit correspondre à la partie « nom » du nomso, voyez plus bas.

nomso-version-numéro est la partie version du nomso de la bibliothèque. Le nomso est ce qui doit coller exactement pour que la bibliothèque soit reconnue par l'éditeur des liens dynamiques, et il est habituellement de la forme : nom.so.version-numéromajeur, et dans ce cas libz.so.1[53]. La partie version est la partie qui suit .so., et donc ici : 1.

dépendances possède le même format qu'un champ de dépendances dans le fichier de contrôle d'un paquet binaire. Cette partie donnera des renseignements sur les paquets qui sont demandés pour compiler un binaire avec la version de la bibliothèque contenue dans le paquet. Voir La syntaxe des champs de relation, Section 7.1 pour des précisions.

Dans notre exemple, si la première version du paquet zlib1g, contenant un numéro mineur égal à au moins 1.3, était de 1:1.1.3-1, alors l'entrée shlibs pour cette bibliothèque pourra énoncer :

     libz 1 zlib1g (>= 1:1.1.3)

La dépendance pour une version particulière sert à éviter les avertissements de l'éditeur de liens dynamiques au sujet de l'utilisation d'anciennes bibliothèques avec des binaires plus récents.


8.6.4 Comment créer un fichier shlibs ?

Si le paquet fournit une bibliothèque partagée, vous devez créer un fichier shlibs en suivant le format décrit plus haut. Habituellement, on le nomme debian/shlibs (mais si le paquet contient plusieurs binaires, on pourra l'appeler debian/shlibs.package). Puis on laissera debian/rules l'installer dans la zone de contrôle :

     install -m644 debian/shlibs debian/tmp/DEBIAN

ou, en cas de paquet avec de multiples binaires :

     install -m644 debian/shlibs.package debian/package/DEBIAN/shlibs

Une autre façon de faire est de créer directement le fichier shlibs dans la zone de contrôle à partir du fichier debian/rules sans utiliser un fichier debian/shlibs[54], puisque le fichier debian/shlibs lui-même est ignoré par le programme dpkg-shlibdeps.

Comme dpkg-shlibdeps lit tous les fichiers DEBIAN/shlibs de tous les paquets binaires construits à partir du paquet source, tous les fichiers DEBIAN/shlibs seront installés avant d'appeler dpkg-shlibdeps pour chaque paquet binaire.


8.6.5 Comment écrire le fichier debian/shlibs.local ?

Ce fichier est prévu seulement pour une correction temporaire quand les binaires ou les bibliothèques dépendent d'une bibliothèque pour laquelle aucun fichier shlibs correct n'est produit par le paquet.

Nous supposons que vous essayez de créer un paquet binaire foo. Quand vous essayez d'exécuter dpkg-shlibdeps, vous obtenez le message d'erreur suivant (l'option -O affiche les informations de dépendance sur stdout au lieu de les écrire dans le fichier debian/substvars, et les lignes ont été enveloppées pour faciliter la lecture) :

     $ dpkg-shlibdeps -O debian/tmp/usr/bin/foo
     dpkg-shlibdeps: warning: unable to find dependency
       information for shared library libbar (soname 1,
       path /usr/lib/libbar.so.1, dependency field Depends)
     shlibs:Depends=libc6 (>= 2.2.2-2)

Vous pouvez alors exécuter ldd sur le binaire pour trouver l'emplacement exact de la bibliothèque en question :

     $ ldd foo
     libbar.so.1 => /usr/lib/libbar.so.1 (0x4001e000)
     libc.so.6 => /lib/libc.so.6 (0x40032000)
     /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

Ainsi le binaire foo dépend de la bibliothèque partagée libbar, mais aucun paquet ne donne un fichier *.shlibs qui gère libbar.so.1 dans /var/lib/dpkg/info/. Déterminons le paquet responsable :

     $ dpkg -S /usr/lib/libbar.so.1
     bar1: /usr/lib/libbar.so.1
     $ dpkg -s bar1 | grep Version
     Version: 1.0-1

Ce qui nous indique que le paquet bar1, version 1.0-1, est celui qu'on utilise. Maintenant nous pouvons envoyer un rapport de bogue contre le paquet bar1 et créer notre propre fichier debian/shlibs.local pour corriger localement le problème évoqué. Insérer la ligne suivante dans le fichier debian/shlibs.local :

     libbar 1 bar1 (>= 1.0-1)

permettra la construction du paquet.

Dès que le responsable de bar1 fournit un fichier shlibs correct, vous supprimerez cette ligne dans le fichier debian/shlibs.local. Vous aurez sans doute aussi un champ Build-Depends concernant les versions pour bar1 de manière à s'assurer que d'autres n'aient pas le même problème pour construire votre paquet.


[ précédent ] [ Table des matières ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ 11 ] [ 12 ] [ A ] [ B ] [ C ] [ D ] [ E ] [ F ] [ G ] [ suivant ]


La Charte Debian

version 3.7.2.2

La liste de diffusion Debian-Policy