Annexe A. Empaquetage avancé

Table des matières

A.1. Bibliothèques partagées
A.2. Gestion de debian/paquet.symbols
A.3. Multiarchitecture
A.4. Construction d'un paquet de bibliothèque partagée

Voici quelques conseils et pointeurs pour des sujets d'empaquetage avancé auxquels vous serez sans doute confrontés. La lecture de toutes les références suggérées ici est vivement recommandée.

A.1. Bibliothèques partagées

Avant d'empaqueter des bibliothèques partagées, vous devriez lire les références essentielles suivantes avec attention :

Voici quelques conseils simplifiés à l'extrême pour commencer :

  • les bibliothèques partagées sont des fichiers objet ELF contenant du code compilé ;

  • les bibliothèques partagées sont distribuées en fichiers *.so (pas en fichiers *.a ni en fichiers *.la) ;

  • les bibliothèques partagées sont surtout utilisées pour partager du code commun à plusieurs exécutables avec le mécanisme ld ;

  • les bibliothèques partagées sont parfois utilisées pour fournir plusieurs greffons à un exécutable avec le mécanisme dlopen ;

  • les bibliothèques partagées exportent des symboles qui représentent des objets compilés comme des variables, des fonctions et des classes ; elles permettent d'être accédées à partir des exécutables liés ;

  • le SONAME d'une bibliothèque partagée libtruc.so.1 : objdump -p libtruc.so.1 | grep SONAME ;[89]

  • le SONAME d'une bibliothèque partagée correspond normalement au nom du fichier de bibliothèque (mais pas toujours) ;

  • le SONAME d'une bibliothèque partagée liée à /usr/bin/truc : objdump -p /usr/bin/truc | grep NEEDED ;[90]

  • libtruc1 : le paquet de bibliothèque pour la bibliothèque partagée libtruc.so.1 avec la version d'ABI SONAME 1 ;[91]

  • les scripts du responsable du paquet de bibliothèque doivent appeler ldconfig dans des circonstances particulières pour créer les liens symboliques nécessaires au SONAME ;[92]

  • libtruc1-dbg : le paquet de symboles de débogage qui contient les symboles de débogage du paquet de bibliothèque partagée libtruc1 ;

  • libtruc-dev : le paquet de développement qui contient les fichiers d'en-têtes, etc. de la bibliothèque partagée libtruc.so.1 ;[93]

  • les paquets Debian ne devraient normalement pas contenir de fichiers d'archive Libtool *.la ;[94]

  • les paquets Debian ne devraient normalement pas utiliser RPATH ;[95]

  • bien qu'il soit dépassé et que ce ne soit qu'une référence secondaire, le guide d'empaquetage de bibliothèques Debian peut encore être utile.

A.2. Gestion de debian/paquet.symbols

Lors de l'empaquetage d'une bibliothèque partagée, il faut créer un fichier debian/paquet.symbols pour gérer la version minimale associée à chaque symbole pour les modifications d'ABI rétrocompatibles sous le même SONAME de la bibliothèque pour le même nom de paquet de bibliothèque partagée.[96] Vous devriez lire les références essentielles suivantes avec attention :

Voici un exemple grossier de création du paquet libtruc1 à la version amont 1.3 avec le fichier debian/libtruc1.symbols adéquat :

  • préparer le squelette d'arborescence source Debian en utilisant le fichier amont libtruc-1.3.tar.gz :

    • s'il s'agit du premier empaquetage du paquet libtruc1, créer le fichier vide debian/libtruc1.symbols ;

    • si la version amont précédente 1.2 a été empaquetée en tant que paquet libtruc1 contenant le fichier debian/libtruc1.symbols adéquat dans son paquet source, le réutiliser ;

    • si la version amont précédente 1.2 n'a pas été empaquetée avec le fichier debian/libtruc1.symbols adéquat, le créer comme fichier symbols à partir de tous les paquets binaires disponibles de même nom de paquet de bibliothèque partagée contenant le même SONAME de la bibliothèque, par exemple de versions 1.1-1 et 1.2-1 :[98]

      $ dpkg-deb -x libtruc1_1.1-1.deb libtruc1_1.1-1
      $ dpkg-deb -x libtruc1_1.2-1.deb libtruc1_1.2-1
      $ : > symbols
      $ dpkg-gensymbols -v1.1 -plibtruc1 -Plibtruc1_1.1-1 -Osymbols
      $ dpkg-gensymbols -v1.2 -plibtruc1 -Plibtruc1_1.2-1 -Osymbols
      
  • essayer de construire depuis l'arborescence source avec des outils comme debuild et pdebuild (en cas d'échecs dus à des symboles manquants, etc., c'est qu'il y a eu des modifications d'ABI non rétrocompatibles qui nécessitent de changer le nom de paquet de bibliothèque partagée en quelque chose comme libtruc1a avant de recommencer) :

    $ cd libtruc-1.3
    $ debuild
    ...
    dpkg-gensymbols: warning: some new symbols appeared in the symbols file: ...
     see diff output below
    --- debian/libtruc1.symbols (libtruc1_1.3-1_amd64)
    +++ dpkg-gensymbolsFE5gzx        2012-11-11 02:24:53.609667389 +0900
    @@ -127,6 +127,7 @@
      truc_get_name@Base 1.1
      truc_get_longname@Base 1.2
      truc_get_type@Base 1.1
    + truc_get_longtype@Base 1.3-1
      truc_get_symbol@Base 1.1
      truc_get_rank@Base 1.1
      truc_new@Base 1.1
    ...
    
  • si un différentiel est affiché par dpkg-gensymbols comme ci-dessus, extraire le fichier symbols du paquet binaire généré de la bibliothèque partagée :[99]

    $ cd ..
    $ dpkg-deb -R  libtruc1_1.3_amd64.deb libtruc1-tmp
    $ sed -e 's/1\.3-1/1\.3/' libtruc1-tmp/DEBIAN/symbols \
            >libtruc-1.3/debian/libtruc1.symbols
    
  • construire les paquets pour la publication avec des outils comme debuild et pdebuild :

    $ cd libtruc-1.3
    $ debuild clean
    $ debuild
    ...
    

En plus des exemples précédents, il faut vérifier plus profondément la compatibilité d'ABI et changer vous-même les versions de certains symboles si nécessaire. [100]

Bien que ce ne soit qu'une référence secondaire, le wiki Debian sur l'utilisation de fichiers symboles et les pages web qui y sont liées peuvent être utiles.

A.3. Multiarchitecture

La fonctionnalité de multiarchitecture introduite dans Debian Wheezy intègre la prise en charge pour l'installation interarchitecture de paquets binaires (en particulier entre i386 et amd64, mais aussi d'autres combinaisons) dans dpkg et apt. Vous devriez lire les références suivantes avec attention :

Cela utilise le triplet du style i386-linux-gnu et x86_64-linux-gnu pour le chemin d'installation des bibliothèques partagées. Le chemin de triplet réel et défini dynamiquement dans la valeur $(DEB_HOST_MULTIARCH) par dpkg-architecture(1) pour chaque construction. Par exemple, le chemin d'installation de bibliothèques multiarchitectures est modifié comme ceci :[101]

Ancien cheminChemin multiarchitecture i386Chemin multiarchitecture amd64
/lib//lib/i386-linux-gnu//lib/x86_64-linux-gnu/
/usr/lib//usr/lib/i386-linux-gnu//usr/lib/x86_64-linux-gnu/

Voici quelques exemples typiques de scénarios de découpage de paquet multiarchitecture pour les paquets suivants :

  • une bibliothèque source libtruc-1.tar.gz ;

  • un outil source bidule-1.tar.gz écrit en langage compilé ;

  • un outil source machin-tar.gz écrit en langage interprété :

PaquetArchitectureMulti-ArchContenu du paquet
libtruc1anysame la bibliothèque partagée, co-installable
libtruc1-dbganysame les symboles de débogage de bibliothèque partagée, co-installable
libtruc-devanysame les fichiers d'en-tête, etc. de bibliothèque partagée, co-installable
libtruc-toolsanyforeign les programmes de prise en charge en cours d'exécution, non co-installable
libtruc-docallforeign les fichiers de documentation de bibliothèque partagée
biduleanyforeign les fichiers du programme compilé, non co-installable
bidule-docallforeign les fichiers de documentation du programme
machinallforeign les fichiers du programme interprété

Veuillez remarquer que le paquet de développement devrait contenir un lien symbolique vers la bibliothèque partagée associée sans numéro de version. Par exemple : /usr/lib/x86_64-linux-gnu/libtruc.solibtruc.so.1.

A.4. Construction d'un paquet de bibliothèque partagée

Un paquet de bibliothèque partagée peut être construit en activant la prise en charge multiarchitecture en utilisant dh(1) comme ceci :

  • mettre à jour debian/control :

    • ajouter Build-Depends: debhelper (>= 9) à la section du paquet source ;

    • ajouter Pre-Depends: ${misc:Pre-Depends} pour chaque paquet binaire de bibliothèque partagée ;

    • ajouter la définition Multi-Arch: à chaque section de paquet binaire ;

  • définir debian/compat à « 9 » ;

  • ajuster le chemin classique /usr/lib/ en /usr/lib/$(DEB_HOST_MULTIARCH)/ multiarchitecture pour tous les scripts d'empaquetage :

    • appeler d'abord DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) dans debian/rules pour définir la variable DEB_HOST_MULTIARCH ;

    • remplacer /usr/lib/ par /usr/lib/$(DEB_HOST_MULTIARCH)/ dans debian/rules ;

    • si ./configure est utilisé par la cible override_dh_auto_configure dans debian/rules, assurez-vous de le remplacer par dh_auto_configure -- ;[102]

    • remplacer toutes les occurrences de /usr/lib/ par /usr/lib/*/ dans les fichiers debian/truc.install ;

    • générer les fichiers comme debian/truc.links à partir de debian/truc.links.in dynamiquement en ajoutant un script à la cible override_dh_auto_configure dans debian/rules :

      override_dh_auto_configure:
              dh_auto_configure
              sed 's/@DEB_HOST_MULTIARCH@/$(DEB_HOST_MULTIARCH)/g' \
                      debian/truc.links.in > debian/truc.links
      

Veuillez vous assurer d'avoir vérifié que le paquet de bibliothèque partagée ne contient que les fichiers attendus, et que le paquet -dev fonctionne toujours.

Tous les fichiers installés simultanément par des paquets multiarchitectures au même endroit devraient avoir exactement le même contenu. Vous devez faire attention aux différences générées par l'ordre des octets de données (boutisme) et par les algorithmes de compression.



[89] Alternative : readelf -d libtruc.so.1 | grep SONAME.

[90] Alternative : readelf -d libtruc.so.1 | grep NEEDED.

[96] Les modifications d'ABI non rétrocompatibles devraient normalement nécessiter une mise à jour du SONAME de la bibliothèque et du nom de paquet de la bibliothèque partagée.

[97] Pour les bibliothèques C++ et d'autres cas lorsque du suivi de symboles individuels est trop compliqué, suivez plutôt la Charte Debian , 8.6.4 « Le système de shlibs ».

[98] Toutes les versions précédentes des paquets Debian sont disponibles sur http://snapshot.debian.org/. La révision Debian est supprimée de la version pour faciliter le rétroportage du paquet : 1.1 << 1.1-1~bpo70+1 << 1.1-1 et 1.2 << 1.2-1~bpo70+1 << 1.2-1

[99] La révision Debian est supprimée de la version pour faciliter le rétroportage du paquet : 1.1 << 1.3 << 1.3-1~bpo70+1 << 1.3-1

[101] Certains anciens chemins de bibliothèques particulières comme /lib32/ et /lib64/ ne sont plus utilisés.

[102] Sinon, les arguments --libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) et --libexecdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) peuvent être ajoutés à ./configure. Veuillez remarquer que --libexecdir indique le chemin par défaut pour installer les programmes exécutables démarrés par d'autres programmes plutôt que par des utilisateurs. Sa valeur Autotools par défaut est /usr/libexec/ mais sa valeur Debian par défaut est /usr/lib/.