Annexe A. Empaquetage avancé

# Annexe A. Empaquetage avancé

La réécriture de ce tutoriel avec des contenus à jour et des exemples pratiques supplémentaires est disponible sur Guide du responsable Debian. Veuillez utiliser ce nouveau tutoriel comme document principal.

Voici quelques conseils et indications 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.

Vous pouvez avoir besoin d’éditer vous-mêmes les fichiers de modèle d’empaquetage produits par la commande dh_make pour répondre à des préoccupations de ce chapitre. La nouvelle commande debmake devrait le faire de meilleure façon.

## 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 :

- Charte Debian, 8 « Bibliothèques partagées » ;

- Charte Debian, 9.1.1 « Structure de système de fichiers » ;

- Charte Debian, 10.2 « Bibliothèques ».

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 qu’on y accède à partir des exécutables liés ;

- le SONAME d'une bibliothèque partagée `lib`truc`.so`.`1` : `objdump -p lib`truc`.so.`1` | grep SONAME` ;[87]

- 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` ;[88]

- `lib`truc``1`` : le paquet de bibliothèque pour la bibliothèque partagée `lib`truc`.so.`1`` avec la version `1` d'ABI SONAME ;[89]

- 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 ;[90]

- `lib`truc``1`-dbg` : le paquet de symboles de débogage qui contient les symboles de débogage du paquet de bibliothèque partagée `lib`truc``1`` ;

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

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

- les paquets Debian ne devraient normalement pas utiliser RPATH ;[93]

- 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.[94] Vous devriez lire les références essentielles suivantes avec attention :

- Charte Debian, 8.6.3 « Le système de symboles » ;[95]

- dh_makeshlibs(1) ;

- dpkg-gensymbols(1) ;

- dpkg-shlibdeps(1) ;

- deb-symbols(5).

Voici un exemple grossier de la manière de créer le paquet `libtruc1` à partir de 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` :[96]

        $ 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` adéquat mis à jour du paquet binaire généré de la bibliothèque partagée :[97]

      $ 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. [98]

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 :

- wiki Ubuntu sur la spécification multiarchitecture (amont) ;

- wiki Debian sur le multiarchitecture et son implémentation (situation dans Debian).

Elle utilise un 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 est défini dynamiquement dans la variable `$(DEB_HOST_MULTIARCH)` par la commande dpkg-architecture(1) pour chaque construction de paquet binaire. Par exemple, le chemin d'installation de bibliothèques multiarchitectures est modifié comme suit :[99]

Ancien chemin | Chemin multiarchitecture i386 | Chemin 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 `lib`truc`-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é :

Paquet | Architecture | Multi-Arch | Contenu du paquet
--- | --- | --- | ---
`lib`truc``1`` | any | same | la bibliothèque partagée, co-installable
`lib`truc``1`-dbg` | any | same | les symboles de débogage de bibliothèque partagée, co-installable
`lib`truc`-dev` | any | same | les fichiers d'en-tête, etc., de bibliothèque partagée, co-installable
`lib`truc`-tools` | any | foreign | les programmes de prise en charge en cours d'exécution, non co-installable
`lib`truc`-doc` | all | foreign | les fichiers de documentation de bibliothèque partagée
``bidule`` | any | foreign | les fichiers du programme compilé, non co-installable
``bidule`-doc` | all | foreign | les fichiers de documentation du programme
``machin`` | all | foreign | 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.so` → `libtruc.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 (>=10)` à 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` à « 10 » ;

- 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 --`, [100]

  - 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.

## A.5. Paquet Debian natif

Si un paquet est maintenu uniquement pour Debian ou simplement pour un usage local, ses sources peuvent contenir tous les fichiers `debian/*`. Il existe deux façons de l’empaqueter.

Vous pouvez créer l’archive amont en excluant les fichiers `debian/*` et l’empaqueter comme un paquet Debian non natif comme dans Section 2.1, « Processus de construction de paquet Debian ». C’est la méthode normale que certaines personnes préconisent d’utiliser.

L’autre méthode est d’utiliser la manière de procéder pour un paquet Debian natif.

- créer le paquet source Debian natif au format `3.0 (native)` en utilisant un seul fichier tar compressé où tous les fichiers sont intégrés :

  - ``paquet`_`version`.tar.gz`
  - ``paquet`_`version`.dsc`

- construire les paquets binaires Debian à partir du paquet source Debian natif :

  - ``paquet`_`version`_`arch`.deb`

Par exemple, si vous avez des fichiers source dans `~/mypackage-1.0` sans les fichiers `debian/*`, vous pouvez créer un paquet natif Debian en utilisant la commande dh_make comme suit :

    $ cd ~/monpaquet-1.0
    $ dh_make --native

Alors le répertoire `debian` et son contenu sont créés comme en Section 2.8, « Paquet Debian non natif initial ». Aucune archive compressée n'est créée puisqu'il s'agit d'un paquet Debian natif, mais c'est la seule différence. La suite de l'empaquetage est à peu près similaire.

Après exécution de la commande dpkg-buildpackage, les fichiers suivants apparaîtront dans le répertoire parent :

- `monpaquet_1.0.tar.gz`

  c'est l'archive compressée du code source créé à partir du répertoire `monpaquet-1.0` par la commande dpkg-source (il ne se termine pas par `orig.tar.gz`) ;

- `monpaquet_1.0.dsc`

  c'est un résumé du contenu du code source comme dans un paquet Debian non natif (il n'y a pas de révision Debian) ;

- `monpaquet_1.0_i386.deb`

  c'est le paquet binaire terminé comme dans un paquet Debian non natif (il n'y a pas de révision Debian) ;

- `monpaquet_1.0_i386.changes`

  ce fichier décrit toutes les modifications effectuées dans la version actuelle du paquet comme dans un paquet Debian non natif (il n'y a pas de révision Debian).

[87] Alternative : `readelf -d lib`truc`.so.`1` | grep SONAME`.

[88] Alternative : `readelf -d lib`truc`.so.`1` | grep NEEDED`.

[89] Consultez la Charte Debian, 8.1 « Bibliothèques partagées au moment de l'exécution ».

[90] Consultez la Charte Debian, 8.1.1 « ldconfig ».

[91] Consultez la Charte Debian, 8.3 « Bibliothèques statiques » et la Charte Debian, 8.4 « Fichiers de développement ».

[92] Consultez le wiki Debian sur l'objectif de publication relatif à la suppression des fichiers `*.la`.

[93] Consultez le wiki Debian sur les problèmes avec RPATH`*.la`.

[94] 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.

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

[96] 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`

[97] 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`

[98] Consultez la Charte Debian, 8.6.2 « Modifications d'ABI dans les bibliothèques partagées ».

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

[100] 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/`.

Chapitre 9. Envoi de paquet |  |