On doit construire les paquets qui contiennent des bibliothèques partagées avec un peu de soin pour 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).
Tout d'abord, le paquet installera les bibliothèques partagées sous leurs vrais
noms. Par exemple, le paquet libgdbm1 installera
libgdbm.so.1.7.3 en tant que
/usr/lib/libgdbm.so.1.7.3. 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.
Ensuite, le paquet comportera le lien symbolique que ldconfig
voudra créer pour les bibliothèques partagées. Par exemple, le paquet
libgdbm1
inclura un lien symbolique de
/usr/lib/libgdbm.so.1.7.3 vers libgdbm.so.1.7.3.
C'est nécessaire pour que l'éditeur de liens dynamique (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
[31].
Troisièmement, le paquet de développement associé comportera un lien symbolique
pour la bibliothèque partagée sans numéro de version. Par exemple, le paquet
libgdbm1-dev inclura un lien symbolique de
/usr/lib/libgdbm.so vers libgdbm.so.1.7.3. Ce lien
symbolique est nécessaire à ld
quand il compile les paquets ; il
cherche en effet seulement libgdbm.so pour une compilation
dynamique.
Tout paquet qui installe des bibliothèques partagées dans l'un des répertoires
par défaut de l'éditeur de liens dynamique, (actuellement,
/usr/lib et /lib) ou dans un répertoire listé par
/etc/ld.so.conf [32]
doit appeler ldconfig
dans son script postinst
si le
premier argument est configure, et l'appellera dans le script
postrm
si le premier argument est remove.
Cependant, les scripts postrm
et preinst
ne
doivent pas appeler ldconfig
dans le cas où le paquet est mis
à jour (voir Précisions sur la phase de
dépaquetage lors d'une installation ou d'une mise à jour, Section 6.5) ; en
effet ldconfig
voit les noms temporaires que dpkg
donne à ces fichiers lors de l'installation ; et il fait pointer les liens des
bibliothèques partagées sur ces noms, juste avant que dpkg
,
continuant l'installation, ne change le nom de ces fichiers temporaires !
Quand un paquet contient un binaire ou une bibliothèque qui se lient à 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 [33].
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.
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é.)
Cela donne les remplacements à faire pour ce paquet. Son usage est décrit plus bas (Comment écrire le fichier debian/shlibs.local ?, Section 9.6).
Cela donne les remplacements à faire pour tout le système. Cette liste, maintenue par l'administrateur local, est normalement vide.
Quand on construit un paquet, tous les fichiers debian/shlibs sont copiés dans le répertoire temporaire de construction avec comme nom shlibs. Ces fichiers donne des renseignements sur toutes les bibliothèques partagées contenues dans le paquet [34].
Ce sont tous les fichiers shlibs de tous les paquets installés sur le système ; ils sont maintenus par les responsables des paquets concernés.
Ce fichier liste toutes les bibliothèques partagées dont les paquets n'ont pas pu fournir de fichiers shlibs corrects. Il était utilisé quand on a introduit le système shlibs pour la première fois ; il est maintenant normalement vide. Il est maintenu par le responsable de dpkg.
dpkg-shlibdeps
et les fichiers shlibs ?
Placer 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/*
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 [35].
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
${shlib: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 9.6).
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. Voyez dpkg-shlibdeps(1)
pour des renseignements
supplémentaires sur ces options.
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 dependences ...\
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 le l'éditeur de liens dynamique, et il est habituellement de la forme : nom.so.version-numéromajeur, et dans ce cas libz.so.1[36]. La partie version est la partie qui suit .so., et donc ici : 1.
dependences possède le même format qu'un champ de dépendance 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 dynamique au sujet de l'utilisation d'anciennes bibliothèques avec des binaires plus récents.
Si le paquet fournit une bibliothèque partagée, on créera 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
où, en cas de paquet avec de multiples binaires :
install -m644 debian/shlibs.package debian/package/DEBIA\N/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[37],
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.
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 assumons 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'endroit exact de la bibliothèque en question :
$ ldd foo libbar.so.1 => /usr/lib/libbar.so.1 (0x4001e000) $ 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.)
La Charte Debian
version 3.5.6.1 cvs 1.68 03/2002ijackson@gnu.ai.mit.edu
schwarz@debian.org
bweaver@debian.org
debian-policy@lists.debian.org