--- categories: Debian title: Howto packaging Debian ... * Charte Debian : * Référence du développeur Debian : * Guide du nouveau responsable Debian : * Howto sur le wiki Debian : * Howto de Lucas Nussbaum : * Statut de cette page : test / bookworm ## Mise en place de l’environnement de développement ### Préambule Pour construire des paquets sur la machine locale, sans être superutilisateur ni utiliser `sudo(1)`, `sbuild(1)` (qui est utilisé par Debian pour son [infrastructure de construction automatique](https://buildd.debian.org/)) peut être utilisé. Le wiki Debian donne de nombreuses informations sur [l’installation et la configuration de sbuild](https://wiki.debian.org/sbuild), ce qui suit ne présente que le strict nécessaire. Seules les premières étapes (mise en place) nécessitent d’être superutilisateur. ### Installation, configuration minimale ~~~ # apt install sbuild schroot git-buildpackage debootstrap debhelper # sbuild-adduser ~~~ `usermod(8)` ou `addgroup(8)` et `newgrp(1)` peuvent être utilisés à la place de `sbuild-adduser(8)`. ### Création des chroots nécessaires (Sid, Bookworm, Bullseye, etc.) ~~~ # sbuild-createchroot --include=eatmydata,ccache unstable /srv/chroot/unstable-amd64-sbuild http://mirror.evolix.org/debian # sbuild-createchroot --include=eatmydata,ccache bookworm /srv/chroot/bookworm-amd64-sbuild http://mirror.evolix.org/debian # sbuild-createchroot --include=eatmydata,ccache bullseye /srv/chroot/bullseye-amd64-sbuild http://mirror.evolix.org/debian ~~~ ### Maintenance : mise à jour des chroots Cette opération peut être réalisée régulièrement, ou avant de construire des paquets. ~~~ # sbuild-update -udcar unstable bookworm bullseye ~~~ ### Configuration de git-buildpackage Cette configuration assure que `sbuild(1)` soit appelé par `gbp(1)` lors de la [construction](#construction). ~~~ $ cat > ~/.gbp.conf < (pour vim) ## Création d’un paquet ### Utilisation de git buildpackage Il existe plus d’une façon de gérer les paquets Debian, nous proposons ici la [maintenance de paquet avec gbp en lien avec le dépôt amont](https://honk.sigxcpu.org/projects/git-buildpackage/manual-html/gbp.import.upstream-git.html#gbp.import.upstream.git.tarball). À l’initialisation, nous créons un nouveau dépôt Git, et chargeons l’historique amont dans une branche `upstream`. ~~~ mkdir $nouveau_paquet cd $nouveau_paquet git init git remote add upstream https://git.example.org/$upstream_repository.git git fetch --all --tags ~~~ Ensuite nous créons le répertoire `debian/` en utilisant si possible la méthode suivante, avant d’importer la première version amont (de la même façon qu’une [nouvelle version](#nouvelle-version-amont). ### Génération de l'arborescence _debian/_ – Méthode facile Quand c’est possible, s’inspirer d’un paquet existant permet de faciliter l’étape d’initialisation. Il faut donc d’abord trouver un paquet du même genre que le nouveau paquet. Par exemple, pour créer un nouveau paquet [`php-sqlsrv`](https://bugs.debian.org/900572), qui a ses sources dans le [dépôt d’extensions PECL](https://pecl.php.net/), l’idée est de s’inspirer d’un paquet (récemment mis à jour) de l’[équipe PHP PECL](https://qa.debian.org/developer.php?email=team%2Bphp-pecl%40tracker.debian.org) comme [`php-igbinary`](https://tracker.debian.org/php-igbinary). Passons en revue les fichiers et points importants. #### debian/changelog Ne garder qu’une entrée (la première, tout en bas) suffit. Changer le nom du paquet, et s’assurer que la version est inférieure à la version amont cible (pour pouvoir télécharger la dernière version amont plus tard dans le processus). Adapter éventuellement l’entrée principale (après l’astérisque), mais pas la peine de s’embêter avec la dernière ligne contenant l’auteur et la date : elle sera mise à jour par ([gbp](https://packages.debian.org/unstable/git-buildpackage)) [dch](https://packages.debian.org/unstable/devscripts). #### debian/compat Fichier rendu obsolète par debhelper-compat, à supprimer. #### debian/control Pour les paquets PECL, ce fichier est mis à jour automatiquement à partir de `debian/control.in`, il est donc inutile d’éditer ce fichier, passons directement à `debian/control.in`. Modifier le nom du paquet source (`Source`) et binaire (`Package`), les champs `Maintainer` et `Uploaders`, les champs de dépôt (`Vcs-Git` et `Vcs-Browser`), la page d’accueil amont (`Homepage`), et surtout la description (`Description`), courte (synopsys) et longue (suivre les [conseils de la référence du développeur](https://www.debian.org/doc/manuals/developers-reference/best-pkging-practices#the-package-synopsis-or-short-description). Pour les dépendances de construction `Build-Depends`, préférer `debhelper-compat (= 13)` à `debhelper` (et fichier `debian/compat` pour la version). `dh-php (>= 4~)` et `php-all-dev` sont les dépendances nécessaires pour ce type de paquets. Adapter ensuite les dépendances spécifiques (`php-apcu-all-dev` est ici nécessaire à `php-igbinary`, alors que `unixodbc-dev` est nécessaire à `php-sqlsrv`). #### debian/copyright Adaptation nécessaire (mais généralement légère si le paquet pris en point de départ est du même auteur que le nouveau paquet). #### debian/gbp.conf Fichier utile à l’utilisation de [git-buildpackage](https://honk.sigxcpu.org/piki/projects/git-buildpackage/). #### debian/`$paquet`.php, debian/`$extension`.ini Ce sont des spécificités aux paquets PECL, peu d’adaptation est nécessaire (attention tout de même au nom des fichiers). #### debian/rules Rien à adapter dans ce cas, en fonction du type de paquet, les équipes en charge ont généralement des habitudes et outillages permettant de réduire les modifications. #### debian/source/format Devrait toujours contenir `3.0 (quilt)`. #### debian/watch Adapter en fonction de la distribution des sources amont, c’est ce qui permet d’[importer la dernière version](#nouvelle-version-amont). ### Nouvelle version amont Il faut récupérer la nouvelle version amont (lors des mises à jour amont, et lors de la création du nouveau paquet. Si tout a été configuré correctement (cf. supra pour un nouveau paquet), `gbp import-orig --uscan` (ou `uscan(1)` pour un simple téléchargement) permet d’importer la dernière version amont. Les correctifs spécifiques (dans `debian/patches`) peuvent nécessiter une mise à jour s’ils existent (`gbp pq rebase` et `gbp pq export` permettent d’utiliser le workflow Git usuel). Il faut enfin mettre à jour le fichier `debian/changelog`, de préférence avec `gbp dch --multimaint-merge -R --commit` qui mets à jour la version, l’auteur, la date et propose des entrées à adapter. ### Construction du paquet `gbp buildpackage` doit fonctionner avec `sbuild` si les étapes de configuration précédentes ont été suivies. ### Génération de l'arborescence _debian/_ – Méthode traditionnelle Cette étape consiste à créer une arborescence qui constituera le paquet Debian. On peut l'automatiser simplement avec la commande _dh_make_ : ~~~ cd futur-paquet-0.1 dh_make ~~~ _NOTE : le nom du répertoire doit obligatoirement être de la forme _nom_-_version_ (_nom_ peut contenir des minuscules, chiffres et tirets)._ En utilisant dh_make sans options, il essayera de deviner les informations dont il a besoin. On peut forcer celles ci en les spécifiant sur la ligne de commande. Pour les plus utiles : * `-c` : la licence du programme ; * `-e` : l'adresse email du responsable du paquet (vous) ; * `-p` : nom du paquet, si le nom du répertoire courant n'est pas sous la forme standard ; * `-f` : chemin vers l'archive contenant les sources. Si elle n'existe pas, utilisez l'option --createorig. Le type de paquet vous sera demandé lors de l'exécution. #### Édition de certains fichiers importants _dh_make_ a créé de nombreux fichiers dans le répertoire _debian/_. Certains sont indispensables, d'autres moins. Par exemple (si vous ne vous en servez pas) vous pouvez supprimer tous les *.ex, des templates servant d'exemple. [comment]: <> (*pour vim) ~~~ rm *.ex rm *.EX ~~~ Voici une rapide explication à propos des fichiers importants : * le fichier _control_ : il décrit de manière générale le paquet. Plusieurs champs sont à compléter, notamment : * _Section_ : voir la liste [ici](http://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections) ; * _Homepage_ : le site du programme ; * _Architecture_ : _any_ par défaut, ce qui va générer un paquet par architecture. Dans le cas d'un script shell par exemple, on préférera _all_ (un seul paquet est généré car compatible avec toutes les architectures) ; * _Depends_ : indiquez ici le nom et la version des paquets dont dépends éventuellement le programme (en général des bibliothèques) ; * _Description_ : le champ doit contenir une description courte, suivi d'une description longue (sur la ligne suivante, indentée d'un espace). * le fichier _changelog_ : il décrit les changements qui ont été fait sur le programme. À priori, il est déjà complété avec un « Initial release ». Supprimez juste le « (Closes: #nnnn) » puisque c'est la première version. * le fichier _copyright_ : il contient la licence sous laquelle est distribué le programme. `dh_make` l'a partiellement remplit, il vous reste à indiquer le(s) développeur(s) du programme ainsi que le texte de la licence. * le fichier _rules_ : c'est en fait un fichier Makefile, qui décrit les règles de construction et d'installation du paquet. Dans le cas d'un script unique, et qui ne nécessite pas de configuration/compilation : C'est le célèbre _./debian/rules_ qui gère donc la compilation et la copie des fichiers dans la future arborescence. Si l'on simplement copier un script, on peut par exemple rajouter ceci à la fin de la cible _install_ : ~~~ install -d -m 0755 -o root -g root $(CURDIR)/debian/futur-paquet install -m 0755 -o root -g root nom-du-script $(CURDIR)/debian/futur-paquet ~~~ ## Manipulation d'un paquet (binaire) Pour certaines (mauvaises) raisons, on peut être amené à vouloir modifier un paquet binaire... notamment un maintainer script par exemple. ~~~ $ ar x foo.deb $ ls control.tar.gz data.tar.gz debian-binary $ tar xf control.tar.gz $ vim preinst $ tar cvf control.tar.gz md5sums postrm control prerm preinst postinst $ ar r foo.deb control.tar.gz ~~~ Et voilà, on a modifié le _preinst_ du paquet _foo.deb_. ## Paquets simplistes pour administrateurs système (`equivs`) Certains paquets (généralement non officiels) ont parfois des dépendances impossibles à satisfaire, ou non nécessaire dans certains contextes. [equivs](https://packages.debian.org/sid/equivs) propose une alternative simple aux paquets Debian pour satisfaire des dépendances (voir plus). Par exemple, le paquet `mysql-client` n’est pas présent dans Bullseye, mais si en paquet en dépend, le fichier suivant permet de créer un paquet qui fournit `mysql-client` et dépend à la place de `default-mysql-client`. ~~~ $ cat mysql-client.ctl Package: mysql-client Depends: default-mysql-client Version: 8.0 Description: Workaround MySQL client for Ægir Current aegir3-cluster-slave package has unfulfillable dependencies on (at least) Bullseye. ~~~ La construction du paquet prend quelques secondes. ~~~ $ equivs-build mysql-client.ctl […] dpkg-deb: building package 'mysql-client' in '../mysql-client_8.0_all.deb'. […] The package has been created. Attention, the package has been created in the current directory, not in ".." as indicated by the message above! […] # apt install ./mysql-client_8.0_all.deb ~~~ ## FAQ ### Erreur lintian : mkdir -p failed at /usr/share/perl5/Lintian/Unpacker.pm line 224 ~~~ mkdir -p /tmp/temp-lintian-lab-6xngeaELBD/pool/d/devscripts/devscripts_2.13.8_amd64_binary failed at /usr/share/perl5/Lintian/Unpacker.pm line 224. ~~~ C'est probablement que votre système n'a pas assez de mémoire. Avec un _strace lintian_ vous obtiendrez peut-être : ~~~ clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f09117029d0) = -1 ENOMEM (Cannot allocate memory) ~~~