Visite guidée dans la construction
d'un paquet Debian

Un tutoriel pour comprendre les mécanismes de la création des paquets Debian

Sommaire

  1. Prise en main, préliminaires
    1. Environnement de travail
    2. Récupérer le tarball hello-1.0.tar.gz
    3. Renommer le tarball hello-1.0.tar.gz
  2. Construction de notre premier paquet
    1. Mise en place du squelette du paquet
    2. Nettoyage du squelette
    3. Edition du fichier debian/control
    4. Edition du fichier debian/changelog
    5. Le fichier debian/compat
    6. Edition du fichier debian/copyright
    7. Le fichier debian/dirs
    8. Le fichier debian/docs
    9. Le fichier debian/README.Debian
    10. Le fichier debian/rules ou comment le paquet se construit
    11. Modification du Makefile
    12. Création du paquet
  3. Gestion des dépendances
    1. Le programme perroquet
    2. Création du paquet perroquet
    3. Analyse des effets des dépendances

1 - Prise en main, préliminaires

1.1 - Environnement de travail

Avant de commencer, assurons-nous que nous avons tout en main pour travailler. Les paquets suivant sont nécessaires pour pouvoir suivre ce tutoriel:

Verifier que chacun de ces paquets est présent sur le système en utilsant la commande suivante:

$ dpkg -l $package

Où l'on remplacera $package par le paquet à chercher.

1.2 - Récupérer le tarball hello-1.0.tar.gz

Nous allons travailler tout au long de ce tutoriel sur le packaging d'un programme fort complexe et très fameux, le très célèbre hello.

Ce programme une fois correctement installé permet de réaliser la commande suivante:

$ hello
hello world!

Tout notre travail sera de faire en sorte que la simple installation d'un paquet permette de lancer cette commande.

Avant de faire quoi que se soit, nous devons donc récupérer l'archive tar.gz du logiciel, commençons donc par la télécharger :

hello-1.0.tar.gz

1.3 - Renommer le tarball hello-1.0.tar.gz

Il nous faut commencer par renommer cette archive, afin que dpkg-source (qui est appelé lors de la construction du paquet) soit reconnaisse l'archive source du logiciel.

Il poura alors générer un fichier diff.gz qui nous permettra d'analyser les changement que nous avons aportés à l'archive originale.

Renommons donc l'archive ainsi :

$ mv hello-1.0.tar.gz hello_1.0.orig.tar.gz

Tout est maintenant en place pour permettre la Debianisation...


2 - Construction de notre premier paquet

2.1 - Mise en place du squelette du paquet

Le répertoire debian/ constitue la racine des sources d'un paquet. Notre travail va donc se résumer à ajouter ce répertoire dans notre archive, ensuite tout sera fonction de ce que l'on trouvera dans ce répertoire.

Un outil existe pour créer un squelette de répertoire debian propre, il s'agit de dh-make. Il nous suffit de le lancer à partir du répertoire de notre paquet à packager :

$ cd hello-1.0/
$ dh_make

Nous allons désormais devoir répondre à différentes questions:

Type of package: single binary, multiple binary, library, or kernel module?
 [s/m/l/k]

Notre paquet sera un paquet unique (single binary) nous répondons donc s.

En choisissant s, dh_make nous propose plusieurs informations issue de notre nevironnement:

Maintainer name : Alexis Sukrieh
Email-Address   : sukria@sukria.net
Date            : Fri, 22 Apr 2005 16:55:23 +0200
Package Name    : hello
Version         : 1.0
License         : blank
Type of Package : Single
Hit  to confirm:

On notera que les champs « Maintainer name » et « Email-Address » sont renseignés à partir des variables d'environnement suivantes : DEBFULLNAME et DEBEMAIL.

Nous confirmons et obtenons le dernier message de dh_make, nous informant que les fichiers générés dans debian/ ne sont que des bases qu'il nous faudra éditer manuellement. Nous avons égalament un avertissement à propos du Makefile, dh_make nous rappelle qu'il faudra le modifier.

Done. Please edit the files in the debian/ subdirectory now. You should also
check that the hello Makefiles install into $DESTDIR and not in / .
Notre squellette est prêt :
$ ls
debian  hello  Makefile
ls debian/
changelog     copyright  emacsen-install.ex  hello.doc-base.EX  manpage.xml.ex  preinst.ex     watch.ex
compat        cron.d.ex  emacsen-remove.ex   init.d.ex          menu.ex         prerm.ex
conffiles.ex  dirs       emacsen-startup.ex  manpage.1.ex       postinst.ex     README.Debian
control       docs       hello-default.ex    manpage.sgml.ex    postrm.ex       rules

2.2 - Nettoyage du squelette

Avant de commencer à éditer les fichiers clefs du package, nous faire un peu de ménage pour y voir plus clair.

Le squelette généré comporte beaucoup de fichier d'exemples ayant une extension .ex ou .EX, supprimons-les (ce tutoriel n'a pas vocation à détailler chacun de ces fichiers).

$ rm -f debian/*.ex debian/*.EX

2.3 - Edition du fichier debian/control

Commençons par renseigner l'identité de notre paquet, un brouillon a été créé apr dh_make, mais il nous faut le compléter:
Source: hello
Section: unknown
Priority: optional
Maintainer: Alexis Sukrieh <sukria@sukria.net>
Build-Depends: debhelper (>= 4.0.0)
Standards-Version: 3.6.1

Package: hello
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: 
 

Le champs section permet de trier les paquets. Nous choisirons la section misc parmi les sections définie dans le manuel de référence Debian.

Il nous faut également rédiger une description courte pour le paquet, ainsi qu'une description longue. De plus nous allons supprimer les dépendances car notre paquet ne dépend de rien, il ne s'agit que d'un script shell.

Nous allons également changer la valeur du champ Architecture puisque notre programme est un script shell, il peut se lancer sur toutes les architectures. Le mot-clef any signifie qu'il faudra construire un paquet pour chaque architecure, cela est utile pour les programme qu'il faut compiler. Dans notre cas, nous choisirons le mot-clef all qui signifie que le même paquet fonctionnera sur toutes les architectures.

Voici un exemple de ce que nous pourrions faire comme debian/control

Source: hello
Section: misc
Priority: optional
Maintainer: Alexis Sukrieh <sukria@sukria.net>
Build-Depends: debhelper (>= 4.0.0)
Standards-Version: 3.6.1

Package: hello
Architecture: all
Depends: 
Description: basic shell script for printing hello
 This script was written to make the Libreast tutorial possible.
 .
 The only feature is to print on STDIN the string "hello world".   

On notera que le caractère . permet de séparer plusieurs paragraphes.

2.4 - Edition du fichier debian/changelog

Nous devons désormais nous pencher sur l'historique de notre paquet. Le fichier debian/changelog remplit ce rôle grâce à un format particulier. Ce fichier impactera directement le nom du paquet puisqu'il désignera précisément le numéro de version du paquet.

Une norme décrit comment déterminer un numéro de version, on concatène le numéro de version du logiciel (dans notre cas 1.0) avec un tiret, suivi du numéro de version du paquet (dans notre cas, 1).

Notre paquet aura donc pour numéro de version : 1.0-1.

Chacune des entrées de ce fichier décrit une nouvelle version du paquet. On devra y trouver le numéro de version du paquet (qui doit logiquement aller en grandissant), l'auteur du paquet, la date précise du paquetage et au moins une mention de changement (précédée par le caractère *.

Encore une fois, pour nous faciliter la vie, nous allons utiliser un outil : dch (Debian Changelog) :

$ dch

Vi est alors lancé avec une entrée du changelog tout prête (encore une fois les variables d'environnement DEBFULLNAME et DEBEMAIL auront été utilisées) et il ne reste plus qu'à saisir le ou les changement effectués.

Pour notre paquet, une mention suffira :

hello (1.0-1) unstable; urgency=low

  * Initial Release.

 -- Alexis Sukrieh   Fri, 22 Apr 2005 21:18:11 +0200

Et elle a déjà été remplie par dh_make ! Notre utilisation n'aura pas été vaine pour autant puisque le timestamp a été mis à jour...

2.5 - Le fichier debian/compat

Un fichier assez curieux est présent, il se nome compat et ne contien qu'un seul caractère : le chiffre 4.

N'ayons pas la très mauvaise idée de supprimer ce fichier sous pretexte que son contenu est léger ! Son influence sur la constrcution du paquet est bien réelle.

En effet, il décrit sur quel mode de compatibilité les debhelpers doivent se comporter. Les debhelpers sont des outils qui facilitent la vie du mainteneur, par défaut ils sont utilisé dans le squelette que nous avons généré, nous les étudierons plus en détail par la suite.

Nous ne toucherons donc pas à ce fichier, le mode de compatibilité 4 est le dernier et notre paquet sera compatible.

2.6 - Edition du fichier debian/copyright

Nous devons également renseigner les mentions légales relatives à notre paquet afin de permettre à nos utilisateurs de connaiître sous quelles conditions le paquet est utilisable.

Ce fichier rempli cette fonction, il est comme d'habitude pré-rempli, à nous de le compléter:

This package was debianized by Alexis Sukrieh <sukria@sukria.net> on
Fri, 22 Apr 2005 17:03:01 +0200.

It was downloaded from <fill in ftp site>

Copyright Holder: <put author(s) name and email here>

License:

<Put the license of the package here>

Nous avons trouvé un exemplaire de la licence GPL 2.0 dans l'archive que nous avons téléchargé, muni de cette information, nous pouvons remplir les blancs :

Ne nous précipitons pas cependant à copier l'intégralité de la licence GPL 2 dans ce fichier car elle est déjà fournie sur le systèmes Debian. Nous nous contenterons juste d'y faire référence :

This package was debianized by Alexis Sukrieh <sukria@sukria.net> on
Fri, 22 Apr 2005 17:03:01 +0200.

It was downloaded from http://www.sukria.net/confs/libreast_2005/hello-1.0.tar.gz 

Copyright Holder: This software is copyleft (C) 2005  Alexis Sukrieh.

License:

This program is released under the terms of the GPL licence.
         
On Debian systems, the complete text of the GNU General Public
License can be found in /usr/share/common-licenses/GPL.

2.7 - Le fichier debian/dirs

Ce fichier permet, via le debhelper dh_installdirs, de créer des sous-répertoires à notre place. Nous n'avons pas besoin de créer de sous-répertoire pour notre paquet, nous pouvons donc supprimer ce fichier.
$ rm -f debian/dirs

2.8 - Le fichier debian/docs

Ce fichier est vide et nous servira pas, poublelle.
$ rm -f debian/docs

2.9 - Le fichier debian/README.Debian

Ce fichier doit contenir toutes les notes relatives au logiciel paqueté mais directement liés au packaging Debian. Pour notre paquet, aucune note ne sera nécessaire.
$ rm -f debian/README.Debian

2.10 - Le fichier debian/rules ou comment le paquet se construit

Nous voilà arrivé au moment ou nous allons véritablement rentrer dans la construction du paquet en tant que telle. Ce fichier est écrit dans le format d'un Makefile et dispose de plusieurs cibles impératives.

Parmi ces cibles, nous trouvons la cible install qui a pour rôle d'installer tous les fichiers du paquet dans le répertoire temporaire debian/paquet/ (ou bien entendu, paquet est le nom du paquet à créer).

On se rend compte, à la ligne 59 de notre debian/rules, que le Makefile sera appelé avec une variable particulière: DESTDIR :

install: build
        dh_testdir
        dh_testroot
        dh_clean -k
        dh_installdirs

        # Add here commands to install the package into debian/hello.
        $(MAKE) install DESTDIR=$(CURDIR)/debian/hello

Il va donc nous falloir éditer notre Makefile pour lui faire prendre en compte ce nouveau paramètre.

De plus, make est également utilisé dans la cible build-stamp mais nous n'en avons pasbesoin ici puisque nos sources ne nécessitent pas de compilation :

build-stamp: configure-stamp
        dh_testdir

        # Add here commands to compile the package.
        #$(MAKE)
        #docbook-to-man debian/hello.sgml > hello.1

        touch build-stamp

2.11 - Modification du Makefile

Nous en avons terminé avec les fichiers propres au répertoire debian, mais notre travail n'est pas terminé pour autant, il nous faut modifier notre Makefile pour prendre en compte la variable DESTDIR.

Pour l'instant le script hello s'installe dans /usr/bin, nous voulons désormais qu'il aille dans $(DESTDIR)/usr/bin :

DESTDIR=
BINDIR=/usr/bin

install:
        install -d -m 0755 -o root -g root $(DESTDIR)/$(BINDIR)
        install    -m 0755 -o root -g root hello $(DESTDIR)/$(BINDIR)

2.12 - Création du paquet

Nous somme prêt à construire notre paquet ! Nous allons utiliser dpkg-buildpackage pour lancer le processus de création avec l'option -rfakeroot qui nous permet de construire un paquet sans être root :
$ dpkg-buildpackage -rfakeroot
[...]
dh_md5sums
dh_builddeb
dpkg-deb : construction du paquet « hello » dans
« ../hello_1.0-1_all.deb ».
 dpkg-genchanges
 dpkg-genchanges: including full source code in upload
 dpkg-buildpackage: full upload; Debian-native package (full source is included)
Nous pouvons désormais regarder le contenu du paquet grâce à dpkg :
$ dpkg --contents ../hello_1.0-1_all.deb
drwxr-xr-x root/root         0 2005-04-22 22:18:31 ./
drwxr-xr-x root/root         0 2005-04-22 22:18:29 ./usr/
drwxr-xr-x root/root         0 2005-04-22 22:18:29 ./usr/bin/
-rwxr-xr-x root/root        31 2005-04-22 22:18:29 ./usr/bin/hello
drwxr-xr-x root/root         0 2005-04-22 22:18:29 ./usr/sbin/
drwxr-xr-x root/root         0 2005-04-22 22:18:29 ./usr/share/
drwxr-xr-x root/root         0 2005-04-22 22:18:29 ./usr/share/doc/
drwxr-xr-x root/root         0 2005-04-22 22:18:30 ./usr/share/doc/hello/
-rw-r--r-- root/root       249 2005-04-22 22:17:46 ./usr/share/doc/hello/copyright
-rw-r--r-- root/root       152 2005-04-22 22:17:46 ./usr/share/doc/hello/changelog.Debian.gz

Et bien entendu, nous pouvons l'installer en utilisant dpkg :

$ su
# dpkg -i hello_1.0-1_all.deb

3 - Gestion des dépendances

Maintenant que nous avons réalisé un paquet on ne peut plus simple, nous allons complexifier légèrement l'exercice en jouant avec le système de dépendance.

3.1 - Le programme perroquet

Le programme perroquet a pour but de répéter ce que dit son confrère hello. Si /usr/bin/hello est présent, il répète ce qu'il dit, sinon il se termine en affichant un message d'erreur :
if [ -x /usr/bin/hello ]; then
        hello=$(/usr/bin/hello)
        echo "Je répète hello : $hello"
        exit 0
else
        echo "hello n'est pas installé, perroquet ne sait pas quoi dire" >&2
        exit 1
fi

3.2 - Création du paquet perroquet

Commencer par récupérer l'archive du programme perroquet : perroquet-1.0.tar.gz puis réaliser un paquet debian en suivant la méthode expliquée dans le chapitre 2 de ce tutoriel.

3.3 - Analyse des effets des dépendances

Nous allons maintenant éditer le fichier debian/control pour ajouter une dépendance vers notre paquet hello précédemment crée :
Source: perroquet
Section: misc
Priority: optional
Maintainer: Alexis Sukrieh 
Build-Depends: debhelper (>= 4.0.0)
Standards-Version: 3.6.1

Package: perroquet
Architecture: all
Depends: hello (>= 1.0)
Description: basic shell script for wrapping what hello said
 This script was written to make the Libreast tutorial possible.
 .
 This script will call hello and will repeat what it said.

Après avoir effacé hello de votre système, vérifions que la dépendance est prise en compte:

# apt-get remove hello
...
# dpkg -i ../perroquet_1.0-1_all.deb
Sélection du paquet perroquet précédemment désélectionné.
(Lecture de la base de données... 63014 fichiers et répertoires déjà installés.)
Dépaquetage de perroquet (à partir de ../perroquet_1.0-1_all.deb) ...
dpkg : des problèmes de dépendances empêchent la configuration de perroquet :
 perroquet dépend de hello (>= 1.0) ; cependant :
  Paquet hello n'est pas installé.
dpkg : erreur de traitement de perroquet (--install) :
 problèmes de dépendances - laissé non configuré
Des erreurs ont été rencontrées pendant l'exécution :
 perroquet

La dépendance est donc bien prise en compte, nous pouvons le vérifier en installant nos deux paquets simultanément:

# dpkg -i hello_1.0-1_all.deb perroquet_1.0-1_all.deb
Sélection du paquet hello précédemment désélectionné.
(Lecture de la base de données... 63019 fichiers et répertoires déjà installés.)
Dépaquetage de hello (à partir de hello_1.0-1_i386.deb) ...
Préparation du remplacement de perroquet 1.0-1 (en utilisant perroquet_1.0-1_all.deb) ...
Dépaquetage de la mise à jour de perroquet ...
Paramétrage de hello (1.0-1) ...
Paramétrage de perroquet (1.0-1) ...

Voilà, les notions élémentaires de la construction de paquets Debian ont été abordées dans ce tutoriel, j'éspère que cela aura été intéressant :)

Alexis Sukrieh