Chapitre 3. Modification du code source

Table des matières

3.1. Configuration de quilt
3.2. Correction de bogues amont
3.3. Installation des fichiers à leur emplacement
3.4. Bibliothèques différentes

La place manque pour entrer dans tous les détails de modification des sources amont, mais voici quelques étapes fondamentales et problèmes qui reviennent souvent.

Le programme quilt fournit une méthode fondamentale pour enregistrer les modifications du code source amont pour l'empaquetage Debian. Il est utile d'avoir de légères personnalisations du paramétrage par défaut, configurez donc un alias dquilt pour l'empaquetage Debian en ajoutant les lignes suivantes à ~/.bashrc. La deuxième ligne fournit les mêmes fonctionnalités de complétion de l’interpréteur pour la commande dquilt que pour la commande quilt.

alias dquilt="quilt --quiltrc=${HOME}/.quiltrc-dpkg"
complete -F _quilt_completion $_quilt_complete_opt dquilt

Ensuite créez ~/.quiltrc-dpkg comme suit :

d=. ; while [ ! -d $d/debian -a `readlink -e $d` != / ]; do d=$d/..; done
if [ -d $d/debian ] && [ -z $QUILT_PATCHES ]; then
    # dans le cas d'une arborescence de paquet Debian avec $QUILT_PATCHES non configuré
    QUILT_PATCHES="debian/patches"
    QUILT_PATCH_OPTS="--reject-format=unified"
    QUILT_DIFF_ARGS="-p ab --no-timestamps --no-index --color=auto"
    QUILT_REFRESH_ARGS="-p ab --no-timestamps --no-index"
    QUILT_COLORS="diff_hdr=1;32:diff_add=1;34:diff_rem=1;31:diff_hunk=1;33:diff_ctx=35:diff_cctx=33"
    if ! [ -d $d/debian/patches ]; then mkdir $d/debian/patches; fi
fi

Consultez quilt(1) et /usr/share/doc/quilt/quilt.pdf.gz pour apprendre à utiliser quilt.

Si vous trouvez une erreur dans le Makefile amont comme suit, où install: gentoo aurait dû être install: gentoo-target :

install: gentoo
        install ./gentoo $(BIN)
        install icons/* $(ICONS)
        install gentoorc-example $(HOME)/.gentoorc

Corrigez l'erreur et enregistrez-la avec la commande dquilt sous fix-gentoo-target.patch : [22]

$ mkdir debian/patches
$ dquilt new fix-gentoo-target.patch
$ dquilt add Makefile

Modifiez le fichier Makefile comme suit :

install: gentoo-target
        install ./gentoo $(BIN)
        install icons/* $(ICONS)
        install gentoorc-example $(HOME)/.gentoorc

Demandez à dquilt de créer debian/patches/fix-gentoo-target.patch et ajoutez sa description conformément à DEP-3 : Directives pour l'étiquetage des correctifs :

$ dquilt refresh
$ dquilt header -e
... description du correctif

La plupart des logiciels tiers s'installent d'eux-mêmes dans le répertoire /usr/local. Dans Debian, il est réservé à l'usage privé de l'administrateur système, les paquets ne doivent donc pas utiliser de répertoires comme /usr/local/bin, mais devraient plutôt utiliser les répertoires système comme /usr/bin, conformément à la norme de hiérarchie des fichiers (FHS).

Habituellement, make(1) est utilisé pour automatiser la construction du programme et l'exécution de make install installe les programmes directement à l'endroit voulu (d'après la cible install du Makefile). Pour permettre à Debian de fournir des paquets installables préconstruits, il modifie le système de construction pour installer les programmes dans une image de l'arborescence de fichiers créé dans un répertoire temporaire plutôt que dans la destination réelle.

Ces deux différences entre l'installation normale du programme d'un côté et le système d'empaquetage Debian de l'autre peuvent être abordées de façon transparente par le paquet debhelper à l'aide des commandes dh_auto_configure et dh_auto_install si les conditions suivantes sont vérifiées :

  • le Makefile doit suivre les conventions GNU et gérer la variable $(DESTDIR) ; [23]

  • les sources doivent suivre la norme de hiérarchie des fichiers (« Filesystem Hierarchy Standard » ou FHS).

Les programmes qui utilisent GNU autoconf suivent les conventions GNU automatiquement, de tel sorte qu'ils peuvent être facile à empaqueter. Sur cette base et d'autres paramètres, on estime que le paquet debhelper fonctionnera pour 90 % des paquets sans modification intrusive à leur système de construction. L'empaquetage n'est donc pas aussi compliqué qu'il y parait.

Si vous devez modifier le Makefile, vous devriez vous assurer qu'il gère la variable $(DESTDIR). Bien qu'elle ne soit pas configurée par défaut, la variable $(DESTDIR) précède chaque chemin de fichier utilisé par le programme d'installation. Le script d'empaquetage configurera $(DESTDIR) en tant que répertoire temporaire.

Pour un paquet source créant un seul paquet binaire, le répertoire temporaire utilisé par la commande dh_auto_install sera configurée en debian/paquet. [24] Le contenu du répertoire temporaire sera copié sur le système de l'utilisateur qui installera votre paquet, la seule différence est que dpkg placera ces fichiers dans les chemins relatifs au répertoire racine plutôt qu'au répertoire de travail.

Gardez à l'esprit que même si le programme s'installe dans debian/paquet, il doit continuer à s'exécuter correctement quand il est installé à partir du paquet .deb sous le répertoire racine. Vous ne devez donc pas laisser le système de construction coder en dur des chaînes de caractères comme /home/moi/deb/paquet-version/usr/share/paquet dans les fichiers du paquet.

Voici les parties concernées du Makefile de gentoo [25] :

# Emplacement des commandes exécutables lors de « make install »
BIN     = /usr/local/bin
# Emplacement des icônes lors de « make install »
ICONS   = /usr/local/share/gentoo

Les fichiers sont configurés pour s'installer sous /usr/local/. Conformément aux explications précédentes, ce répertoire est réservé pour les utilisations locales de Debian, changez donc ces chemins en :

# Emplacement des commandes exécutables lors de « make install »
BIN     = $(DESTDIR)/usr/bin
# Emplacement des icônes lors de « make install »
ICONS   = $(DESTDIR)/usr/share/gentoo

Les emplacements exacts qui devraient être utilisés pour les exécutables, icônes, documentation, etc., sont décrits dans la norme de hiérarchie des fichiers (FHS). Vous devriez la consulter et lire les sections relatives à votre paquet.

Dès lors, les commandes exécutables devrait être installé sous /usr/bin plutôt que sous /usr/local/bin, la page de manuel sous /usr/share/man/man1 plutôt que sous /usr/local/man/man1 et ainsi de suite. Remarquez qu'il n'y a pas de page de manuel mentionnée dans le fichier Makefile de gentoo, mais comme la Charte Debian exige que chaque programme en ait une, il faudra en créer une plus tard et l'installer dans /usr/share/man/man1.

Certains programmes n'utilisent pas les variables des fichiers Makefile pour définir des chemins comme ceux-ci. Cela signifie que vous risquez de devoir modifier de vrais fichiers sources C pour qu'ils utilisent les emplacements corrects. Mais où, et que chercher exactement ? Vous pouvez le découvrir avec :

$ grep -nr --include='*.[c|h]' -e 'usr/local/lib' .

grep va parcourir récursivement l'arbre des sources et donner le nom des fichiers et le numéro des lignes où il trouve une occurrence.

Modifiez ces fichiers et à ces lignes, remplacez usr/local/lib par usr/lib. Cela peut être automatisé comme suit :

$ sed -i -e 's#usr/local/lib#usr/lib#g' \
        $(find . -type f -name '*.[c|h]')

Afin de confirmer toutes les substitutions, vous pouvez procéder de façon interactive comme suit :

$ vim '+argdo %s#usr/local/lib#usr/lib#gce|update' +q \
        $(find . -type f -name '*.[c|h]')

Ensuite, vous devriez trouver la cible install (chercher la ligne qui commence par install: fonctionne en général) et renommez toutes les références aux répertoires autres que ceux définis au début du Makefile.

À l'origine, la cible install de gentoo était de la forme :

install: gentoo-target
        install ./gentoo $(BIN)
        install icons/* $(ICONS)
        install gentoorc-example $(HOME)/.gentoorc

Corrigez ce bogue amont et enregistrez la modification avec la commande dquilt sous debian/patches/install.patch :

$ dquilt new install.patch
$ dquilt add Makefile

Dans votre éditeur, modifiez cela pour le paquet Debian comme suit :

install: gentoo-target
        install -d $(BIN) $(ICONS) $(DESTDIR)/etc
        install ./gentoo $(BIN)
        install -m644 icons/* $(ICONS)
        install -m644 gentoorc-example $(DESTDIR)/etc/gentoorc

Vous aurez remarqué qu'il y a maintenant une commande install -d avant les autres dans la règle. Elle n'existait pas dans le Makefile d'origine parce qu'habituellement /usr/local/bin et les autres répertoires existent déjà sur le système dans lequel make install est exécuté. Cependant, puisque dans notre cas l'installation se fait dans une arborescence spécifique nouvellement créée, chacun de ces répertoires doit être créé.

D'autres choses peuvent être ajoutés à la fin de la règle, comme l'installation de la documentation additionnelle que l'auteur amont oublie parfois :

        install -d $(DESTDIR)/usr/share/doc/gentoo/html
        cp -a docs/* $(DESTDIR)/usr/share/doc/gentoo/html

Vérifiez soigneusement, et si tout est bon, demandez à dquilt de créer le correctif debian/patches/install.patch et ajoutez sa description.

$ dquilt refresh
$ dquilt header -e
... description du correctif

Vous avez maintenant un ensemble de correctifs.

  1. correction d'un bogue amont : debian/patches/fix-gentoo-target.patch ;

  2. modification spécifique à l'empaquetage Debian : debian/patches/install.patch ;

Chaque fois que vous faites des modifications qui ne sont pas spécifiques à Debian comme debian/patches/fix-gentoo-target.patch, envoyez-les au responsable amont pour qu'elles puissent être intégrées dans la version suivante du programme et que tout le monde puisse en profiter. Évitez aussi de faire des corrections spécifiques à Debian ou Linux — ou même UNIX ! Faites-les portables. Cela rendra vos corrections beaucoup plus faciles à appliquer.

Remarquez que vous ne devez pas envoyer les fichiers debian/* en amont.

Il y a un autre problème courant : des bibliothèques sont souvent différentes d'une plate-forme à l'autre. Par exemple, Makefile peut contenir une référence à une bibliothèque qui n'existe pas sur le système Debian. Dans ce cas, changez-la en une bibliothèque qui existe dans Debian, et qui sert à la même chose.

Supposons qu'une ligne de Makefile (ou Makefile.in) du programme comme suit :

LIBS = -ltruc -lbidule

Si votre programme ne compile pas depuis que la bibliothèque truc n'existe plus et que son équivalent est fournie par la bibliothèque truc2 sur le système Debian, vous pouvez corriger ce problème de construction en debian/patches/truc2.patch en modifiant truc en truc2. [26]

$ dquilt new truc2.patch
$ dquilt add Makefile
$ sed -i -e 's/-ltruc/-ltruc2/g' Makefile
$ dquilt refresh
$ dquilt header -e
... description du correctif


[22] Le répertoire debian/patches devrait maintenant exister si vous avez exécuté dh_make comme décrit auparavant. Cet exemple de manipulation le créé seulement si vous mettez à jour un paquet existant.

[24] Pour un paquet source créant plusieurs paquets binaires, la commande dh_auto_install utilise debian/tmp comme répertoire temporaire alors que la commande dh_install, à l'aide des fichiers debian/paquet-1.install et debian/paquet-2.install, séparera le contenu de debian/tmp dans les répertoires temporaires debian/paquet-1 et debian/paquet-2 pour créer les paquets binaires paquet-1_*.deb et paquet-2_*.deb

[25] Il s'agit simplement d'un exemple pour montrer à quoi le Makefile devrait ressembler. Si le Makefile est créé par la commande ./configure, la bonne façon de modifier ce genre de Makefile est d'exécuter ./configure à partir de la commande dh_auto_configure avec les options par défaut y compris --prefix=/usr.

[26] Si des modifications de l'API existent entre les bibliothèques truc et truc2, les modifications exigées au code source doivent être faites pour correspondre à la nouvelle API.