Deprecated: Assigning the return value of new by reference is deprecated in /srv/www/u-classroom.net/wiki/inc/parserutils.php on line 208

Deprecated: Assigning the return value of new by reference is deprecated in /srv/www/u-classroom.net/wiki/inc/parserutils.php on line 211

Deprecated: Assigning the return value of new by reference is deprecated in /srv/www/u-classroom.net/wiki/inc/parserutils.php on line 421

Deprecated: Assigning the return value of new by reference is deprecated in /srv/www/u-classroom.net/wiki/inc/parserutils.php on line 594

Deprecated: Function split() is deprecated in /srv/www/u-classroom.net/wiki/inc/auth.php on line 154

Warning: Cannot modify header information - headers already sent by (output started at /srv/www/u-classroom.net/wiki/inc/parserutils.php:208) in /srv/www/u-classroom.net/wiki/inc/auth.php on line 245

Warning: Cannot modify header information - headers already sent by (output started at /srv/www/u-classroom.net/wiki/inc/parserutils.php:208) in /srv/www/u-classroom.net/wiki/inc/actions.php on line 370

Warning: Cannot modify header information - headers already sent by (output started at /srv/www/u-classroom.net/wiki/inc/parserutils.php:208) in /srv/www/u-classroom.net/wiki/inc/actions.php on line 374
====== Packagin Debian/Ubuntu ====== ===== Prérequis ===== Installer les paquets suivants :\\ ''debhelper lintian build-essential fakeroot devscripts ubuntu-dev-tools dh-make'' ===== Un paquet, qu'est-ce que c'est ? ===== Toutes les applications, bibliothèques... disponibles dans Ubuntu ne sont pas développés par Ubuntu. Ils sont développés à gauche à droite par des individus, des entreprises, etc qui mettent périodiquement des archives contenant les sources à disposition du public (on parle de release). Un paquet permet d'effectuer l'installation beaucoup plus facilement qu'à partir des sources, de gérer les mises à jours, les différentes version des paquets... Il permet aussi à l'utilisateur d'installer et de mettre à jour très rapidement puisqu'il n'a pas besoin de compiler les sources. Pour cela, le packager (celui qui crée le paquet) ajoute une surcouche à l'archive des sources qui permet de définir le paquet, son nom, ses dépendances (les paquets dont il a besoin pour fonctionner), sa description, les copyrights... Peut être expliquer rapidement le principe des dépendances, de apt, de dpkg (en quelques lignes) pour être sûr de ne larguer personne). * Il existe deux types de paquets : * les paquets binaires sont les fichiers .deb installables sur votre pc. Ces paquets peuvent être installés par apt grâce aux lignes ''deb http://...'' de votre ''sources.list'' * les paquets sources contiennent le code source du logiciel, et les scripts/données nécessaires à la construction des paquets binaires. Pour pouvoir récupérer des paquets source en utilisant apt, vous devez avoir des lignes de la forme ''deb-src http://x.y.z'' * Plusieurs paquets binaires peuvent être générés à partir d'un paquet source (par exemple le paquet source 'xmoto' génère 2 paquets binaires, 'xmoto' et 'xmoto-data') * Tous les paquets .deb publiés dans les dépôts sont compilés depuis un "paquet source" ===== Étude du contenu d'un paquet debian source ===== ==== Paquet binaire et paquet source ==== Commençons par une petite précision technique. Les paquets binaires sont les paquets (.deb) qui contiennent les fichiers nécessaires à l'application pour pouvoir fonctionner sur votre ordinateur. C'est ce que nous allons nous efforcer de créer. Tous les paquets binaires disponibles dans les dépôts Ubuntu ont été construits à partir de paquets sources. Un paquet source est un ensemble de fichiers (attention le terme de paquet est utilisé par analogie. Il n'y a pas ici de fichier conteneur comme peut l'être le .deb pour les binaires) contenant les sources originelles de l'application, ainsi que les indications des modifications nécessaires à la création du paquet debian. ==== Étude d'un exemple de paquet source ==== Pour illustrer cela, nous allons examiner le contenu d'un paquet source. Pour cela il faut le télécharger d'un des dépôts source configuré pour apt. Commençons par créer le dossier dans lequel nous allons travailler. mkdir ~/packaging && cd ~/packaging Et téléchargeons un paquet source : apt-get source xfce4-xkb-plugin ls Note: il faut avoir la ligne ''deb-src http://archive.ubuntu.com/ubuntu main'' dans /etc/apt/sources.list La commande « ls » nous donne comme contenu : * un répertoire xfce4-xkb-plugin-0.4.3 * et les fichiers suivants : * xfce4-xkb-plugin_0.4.3.orig.tar.gz * xfce4-xkb-plugin_0.4.3-1ubuntu2.dsc * xfce4-xkb-plugin_0.4.3-1ubuntu2.diff.gz Vous obtiendrez exactement ces fichiers si vous êtes sous Ubuntu Intrepid, peut-être une autre version sous d'autres versions de Debian ou d'Ubuntu. Le fichier xfce4-xkb-plugin_0.4.3.orig.tar.gz est en fait l'archive contenant les fichiers sources tels que l'on peut les obtenir sur le site du projet (typiquement ceux que l'on installe avec « ./configure && make && make install »). Le répertoire est d'ailleurs issu de la décompression, de cette archive. Seul le nom du fichier a été changé pour des raisons que nous préciserons plus tard. Le fichier xfce4-xkb-plugin_0.4.3-1.dsc contient la description du paquet source (et des deux autres fichiers, avec leur taille et leur somme MD5). Le fichier xfce4-xkb-plugin_0.4.3-1.diff.gz contient toutes les modifications nécessaires pour construire le paquet Debian. Constituer un paquet source nécessite d'ajouter aux sources existantes un répertoire debian/ avec quelques fichiers. C'est ce répertoire que contient le fichier « .diff.gz ». On maintient ces modifications dans un fichier séparé pour créer une distinction claire entre les fichiers « upstream » et les informations de packaging debian proprement dites. Maintenant que l'on a une idée de ce que sont les paquets sources, nous allons créer notre premier paquet. ===== Création de notre premier paquet ===== ==== Création du paquet source ==== Pour notre exemple nous allons construire le paquet de l'application "u-classroom", créée pour l'occasion. Après avoir supprimé le contenu de notre dossier ''~/packaging'' pour repartir d'une situation propre, on télécharge les sources du dit logiciel. Donc dans ''~/packaging'' : rm -rf * # on nettoie :-) mkdir classroom && cd classroom wget http://u-classroom.net/files/2009-01-29/packaging/classroom-fr-0.1.tar.gz Une fois les sources récupérées, la //première// chose à faire est de renommer le tarball, afin de pouvoir créer un paquet source correct par la suite. Attention le format de ce nom est important. Une erreur ici n'est pas particulièrement désastreuse, mais met en péril la qualité du paquet source. La syntaxe est paquet_version.orig.tar.gz (notez le « _ » à la place du « - » d'origine). Il faut donc exécuter dans le terminal : mv classroom-fr-0.1.tar.gz classroom-fr_0.1.orig.tar.gz Notez le nom similaire au fichier correspondant que nous avons trouvé dans le chapitre précédent. Puis on décompresse cette archive et on entre dans le répertoire contenant les sources : tar zxvf classroom-fr_0.1.orig.tar.gz cd classroom-fr-0.1 Une règle d'or dans la création de paquets est de ne pas toucher au tarball d'origine. La seule chose autorisée est de le renommer (c'est même nécessaire). Ne pas modifier le tarball permet de bien distinguer le travail de l'auteur de celui du packageur. Maintenant que les sources sont là, ainsi que le « .orig.tar.gz », on va pouvoir créer le paquet. Pour cela il faut créer le dossier « debian/ » dans le dossier des sources. Pour créer un squelette de dossier « debian/ », utilisez dh_make, disponible dans le paquet dh-make. Attention, il faut saisir cette commande dans le dossier contenant les sources. Dans notre cas : $ ~/packaging/classroom/classroom-fr-0.1 La commande : dh_make -e votreaddresse@email.tld doit normalement vous retourner ceci : Type of package: single binary, multiple binary, library, kernel module or cdbs? [s/m/l/k/b] Ceci vous permet de préciser quel type de package vous construisez. Ici, choisissez le type de paquet "single" : répondez donc *s* à la question. Pour les curieux, quelques commentaires sur les autres choix : * multiple binary permet de créer plusieurs paquets binaires à partir d'un unique paquet source * library permet de créer un paquet pour une bibliothèque (lib quelque chose) * kernel module : un module pour le noyau (qui nécessite un système particulier) * cdbs est un outil permettant d'automatiser certains aspects (pour le paquets simples, il permet un gain de temps par rapport à l'utilisation de debhelper, mais est peu intéressant pour comprendre ce qui se passe réellement) dh_make affiche ensuite la ligne suivante: Hit to confirm : On confirme avec la touche « Entrée ». On doit maintenant avoir un dossier « debian/ » dans le dossier contenant les sources de notre application. On entre dans ce dossier « debian/ » : cd debian && ls Et là, horreur, plein de fichiers à éditer ! Certains éléments de ce squelette ne nous sont pas utiles ici. On va supprimer le fichier « README.Debian » et les fichiers « *.ex » et « *.EX » (qui sont des fichiers exemples correspondant à des cas particuliers, comme les initscripts, les fichiers relatifs à cron, ou les fichiers .menu, non nécessaires dans le cas d'un paquet simple comme dans cet exemple) avec la commande suivante : rm -f *ex *EX README* && ls Il ne nous reste plus que 7 fichiers : * changelog * compat * control * copyright * docs * rules * dirs Les fichiers « docs » et « dirs » ne sont pas indispensables mais les 5 autres sont absolument essentiels et il va falloir les éditer avec votre éditeur de texte préféré. ==== Le fichier « changelog » ==== Il contient le détail de toute l'évolution du paquet. Pour chaque entrée on a : * nom_du_paquet_source (version_du_paquet) distro; urgency=low * ligne vide * descriptif des changements * ligne vide * nom du packageur jour, date heure timezone Attention à la syntaxe, les espaces et ponctuations ne sont pas anodins. La compilation du paquet source étant très automatisée, les scripts doivent avoir des points de repère solides, et le format des fichiers est donc défini de façon stricte Quelques mots sur les versions de paquets… Une même version d'un logiciel peut être empaquetée plusieurs fois. De même, Ubuntu étant basée sur Debian, il peut exister plusieurs modifications faites dans Ubuntu à partir du même paquet venant de chez Debian. Les versions sont donc de la forme -ubuntu. Ce qui donne pour nous : * si vous packagez pour Debian => 0.1-1 * si vous packagez pour Ubuntu => 0.1-0ubuntu1 (puisque le paquet n'est pas dans Debian) Debian est « upstream » pour Ubuntu (« flux venant d'en haut »), de même que les sources du logiciel sont « upstream » pour Debian et Ubuntu. Il faut donc mettre à jour ce fichier avec : * le nom du paquet ; * la version ; * éventuellement le nom de la distribution que vous utilisez à la place de "unstable". Le « Closes: #nnnn » n'est pas utilisé chez Ubuntu (ça permet de clore automatiquement un bug ITP: « intent to package », utilisé pour annoncer qu'on a l'intention de packager un logiciel particulier dans Debian). Les dates et heures sont à renseigner au format UTC + décalage horaire (format similaire à la sortie de la commande « date -R ». Pour vérifier, voici un exemple de fichier changelog : http://u-classroom.net/files/2009-01-29/packaging/debian/changelog Il est notamment possible d'éditer le fichier changelog avec la commande dch, provenant du paquet devscripts (debchange - Outil pour la maintenance du fichier debian/changelog d’un paquet source). ==== Le fichier « copyright » ==== Le squelette de ce fichier est plutôt clair, pas vraiment besoin de s'étendre dessus. Mais le contenu n'est pas toujours évident à déterminer. Il y a un fichier « COPYING » dans le répertoire source, qui contient dans notre exemple la GPL en entier. Notez que ce n'est pas ce fichier qui sert de référence pour définir la licence, mais les fichiers source (qui contiennent le code, souvent présents dans un dossier « src/ »). Regardez le fichier « main.c » dans les sources : less ../src/main.c Les quatres premiers paragraphes sont ceux à recopier bêtement (et oui) dans « debian/copyright ». Ce sont ces paragraphes qui désignent le nom et l'année du Copyright, ainsi que la licence (pas le fichier « COPYING »). Attention, vérifiez bien tous les fichiers sources ! Plusieurs copyrights ou licences peuvent être utilisés ! Dans notre cas, le fichier « debian/copyright » ressemblera à : http://u-classroom.net/files/2009-01-29/packaging/debian/copyright Il est important de faire attention à ce fichier car s'il est mal renseigné, le détenteur du copyright peut très bien aller jusqu'à vous intenter un procès (la majorité se contenteront d'un mail vous signalant l'erreur et, si vous êtes courtois, n'hésiterons pas à vous aider). Mais soyez prudent(e) malgré tout, certains deviennent susceptibles dès que l'on écorne leur copyright. D'ailleurs, lors de la réalisation d'un package n'hésitez à contacter l'auteur. C'est en général assez apprécié et cela peut vous permettre de faire valider ce fichier directement auprès de la personne concernée. ==== Le fichier « control » ==== C'est le fichier de description du paquet source et de son paquet binaire résultant. Le premier paragraphe décrit le paquet source. Le(s) paragraphe(s) suivant(s) décrit(décrivent) le(s) paquet(s) binaire(s), car il peut y avoir plusieurs paquets binaires générés pour un seul paquet source. Les champs présents dans ce fichier squelette doivent être présents. Jetons d'abord un coup d'oeil aux champs concernant le paquet source : * Source: le nom du logiciel que vous packagez * Section: la catégorie dans laquelle pourra se trouver le paquet source (voir http://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections pour la liste des sections) * Priority: l'importance du paquet. Le kernel a en général une importance plus grande qu'un applet pour le panel KDE ;) * Maintainer: le mainteneur du paquet, en l'occurrence : Prénom Nom * Build-Depends: la liste des paquets nécessaires à la compilation des sources (/!\, les paquets nécessaires à la compilation sont en général différents de ceux nécessaires à l'exécution du programme compilé) * Standards-Version: la version de la "debian policy" actuelle, à laquelle vous devez vous référer (http://www.debian.org/doc/debian-policy/) * Homepage: l'URL de site de l'application La debian policy peut faire peur… mais c'est la référence pour l'empaquetage debian/ubuntu. Jetons ensuite un coup d'oeil aux champs concernant le paquet binaire : * Package: le nom du paquet binaire (qui peut différer du nom du paquet source) * Architecture: l'architecture pour laquelle sera valable le paquet binaire. Ça peut être une architecture unique (i386, powerpc…), une liste, "all" (un seul et même paquet binaire sera utilisable sur toutes les architectures, comme dans le cas d'une application python ou d'un script bash), ou encore "any" (dans ce cas le paquet source doit être compilé sur chacune des architectures disponibles) * Depends: les dépendances du paquet (${shlibs:Depends} sera remplacé plus tard lors de la construction du paquet grâce à un outil fort pratique) * Description: une description courte (d'une ligne), suivie d'une description plus longue (dont chaque ligne commence par un espace). C'est cette description qui apparaît dans les propriétés du paquet dans synaptic. Le plus simple est d'aller chercher un texte dans un fichier readme des sources (s'il y en a un), ou sur le site de l'auteur. Notez que l'on peut indiquer ici les paquets supplémentaires suggérés par l'application à l'aide d'une ligne "Suggests: foo1, foo2, foo3" ou "Recommends: bar1, bar2, bar3". Voici le fichier « control » de notre exemple : http://u-classroom.net/files/2009-01-29/packaging/debian/control La difficulté principale de cette étape est d'indiquer correctement les Build-Depends. Elles peuvent être déterminées en fouillant les sources ou en compilant à la main l'application (grâce aux messages d'erreurs du ./configure notamment, ou en lisant le fichier configure.in/configure.ac pour déterminer quels bibliothèques et programmes sont nécessaires pour compiler). Elles sont quelquefois indiquées sur le site du projet. Attention lors des tests sur votre machine. Il se peut qu'une dépendance nécessaire soit déjà installée et que la compilation fonctionne (à priori) parfaitement. Cependant tous les paquets ubuntu sont compilés dans un environnement vierge. Si la ligne "Build-Depends:" n'est pas exacte, la compilation risque alors d'échouer (pbuilder est un outil indispensable pour tester les Build Depends, nous en reparlerons plus tard). ===== Le paquet « debhelper » ===== Dans la ligne Build-Depends figure la mention d'un paquet particulier : le paquet debhelper. debhelper est un outil qui facilite la vie des empaqueteurs, avec tout un tas de petits scripts dont les noms commencent par 'dh_'. Chacun a un rôle particulier et fonctionne différemment. La commande `man dh_foo` vous apprendra tout ce qu'il faut savoir ;). On verra quelques exemples en regardant le fichier debian/rules. La version actuelle de debhelper est la version 7. Elle introduit de gros changements par rapport à la version 5 (la version 6 a rapidement été remplacée). La version 5 étant encore énormément utilisée, nous avons fait le choix de l'utiliser. La "compatibilité debhelper" (cf paragraphe suivant) correspond à la version majeure de debhelper (c'est donc 5 dans notre cas). `dh_make` peut utiliser par défaut une compatibilité debhelper 4 ou 7 suivant votre environnement. Veillez à mettre à jour les informations (bien que ce ne soit à priori pas vital pour la compilation de votre paquet). ==== Le fichier « compat » ==== Ce fichier sert à indiquer la compatibilité debhelper, en général il contient juste le chiffre correspondant à la version majeure de debhelper. Il est bien sûr impossible d'utiliser un niveau de compat supérieur à la version majeure de debhelper que vous utilisez, et la version recommandée est en général cette version majeure (7 pour intrepid, 6 pour hardy, et 5 pour dapper et gutsy) ==== Le fichier « rules » ==== Le fichier « rules » est un fichier exécutable (plus précisément, c'est un Makefile, pour ceux à qui ça parle). C'est lui qui va servir à piloter la création du paquet binaire. C'est ce fichier qui contient les règles nécessaires à la compilation du paquet. Le principe est simple. Il s'agit tout simplement de compiler le logiciel exactement comme on compile avec `./configure && make` (c'est la règle "build"), et de l'installer (c'est la règle "install") non pas sur le système, mais dans un dossier ("$(CURDIR)/debian/", avec `make install`), avant de pouvoir en faire une archive .deb (c'est la règle "binary-install"). Quel que soit le type de paquet, un certain nombre de ces règles doivent toujours être présentes: * build * clean * binary,binary-arch,binary-indep Vous pouvez trouver plus d'informations à ce propos dans la debian policy, section 4.9 Le fichier rules est un makefile dont chaque cible est appelée lors de la construction du paquet. Chaque partie correspond en fait à une certaine étape de la compilation : * config.status: correspond au `./configure` (avec un paquet d'options dans notre fichier rules) * build: correspond au `make` ($(MAKE)) * install: correspond au `make install` Ici l'installation se fait dans "$(CURDIR)/debian/classroom-fr", donc dans le dossier « debian/ » créé tout à l'heure. Pour avoir des informations sur tous les outils dh_* que vous voyez listés dans ce fichier n'hésitez pas à consulter les pages man. Une bonne partie d'entre elles seront francisées (n'oubliez pas d'installer le paquet manpages-fr pour pouvoir les lire). Une fois arrivé ici notre paquet source est prêt, il ne nous reste plus qu'à le créer vraiment pour pouvoir retrouver les trois fichiers que nous avons vus plus tôt, dans notre premier exemple. ===== Construction du paquet source ===== Pour construire ce paquet : cd .. # on se place à la racine du dossier source : ~/packaging/classroom/classroom-fr debuild -S -sa --lintian-opts -Ii Le '-S' permet de construire un paquet source, le '--lintian-opts -Ii' donne une information sur les messages d'erreur de lintian, le '-sa' permet d'inclure le .orig.tar.gz dans l'upload vers une archive (à retenir lorsque vous uploaderez votre premier paquet sur REVU, le système de QA d'Ubuntu, permettant aux contributeurs de faire rentrer des paquets et surtout, comme son nom l'indique, de les faire vérifier par des MOTUs). La commande utilise automatiquement fakeroot (commande simulant les privilèges super-utilisateur) si rien est précisé (voir le man de debuild). ATTENTION : le paquet source est à reconstruire avec cette commande à chaque fois que vous modifiez quelque chose dans le dossier sources. À ce stade, vous risquez d'être confronté à l'erreur suivante : debuild: fatal error at line 791: running debsign failed Pas de panique, contrairement à ce qui est indiqué ce n'est pas une erreur si fatale que cela. Elle signifie simplement que debuild n'a pas pu signer le paquet avec une clef gpg. Si vous avez une clef gpg associée à l'adresse mail que vous avez indiqué au début, vous pouvez utiliser -k0x12345678 comme paramètre supplémentaire de debuild où 12345678 est remplacé par l’identifiant de 8 caractères de votre clé gpg publique. Pour obtenir cette clef, il vous suffit de la chercher. gpg --list-keys votre_adresse_mail (la dernière option n'est pas obligatoire et permet simplement un tri) Cela renvoie : /home/utilisateur/.gnupg/pubring.gpg ---------------------------------- pub 2048R/clé_publique_de_8_caractères 2007-06-08 uid partie_de_son_uid (commentaire) sub 2048/clé_privé_de_8_caractères 2007-06-08 Votre clef hexadécimale de 8 caractères récupérée , il vous suffit de rajouter un 0x devant afin de l'exploiter dans debuild sous forme : debuild -k0x12345678 -S -sa --lintian-opts -Ii Une autre solution est d'ajouter dans votre fichier .devscripts (dans votre $HOME : le créer si besoin) export DEBSIGN_KEYID= Ces modifications sont prises en compte dès la prochaine exécution, les outils compris dans le paquet devscripts lisent en effet ce fichier à chaque fois qu'il sont lancés. Pour voir le résultat du paquet que vous venez de créer : cd .. && ls Nos trois fichiers constituant le paquet source sont bien présents ! ===== Compilation et création du paquet binaire ===== Une fois l'étape précédente terminée il ne vous reste plus qu'à taper la commande suivante pour compiler votre paquet source (dans « ~/packaging/classroom ») : cd classroom-fr-0.1 dpkg-buildpackage -b (l'option -b spécifie de ne compiler que les paquets binaires, puisque nous venons de créer le paquet source) Et à laisser mariner… en cas d'erreur de dépendance (eh oui cela peut encore arriver pendant la compilation) reprendre à l'étape Création du paquet binaire en ajoutant le paquet manquant avant lancer le build. Une fois cette étape terminée, votre .deb est dans ''~/packaging/classroom'' En dernière étape, nous allons vérifier quelques points : * d'abord les dépendances : dpkg -f ~/packaging/classroom/classroom-fr*deb Notez que la variable ${shlibs:Depends} a été remplacée par une liste de bibliothèques (avec précision des versions pour certaines). * la liste des fichiers contenus dans le .deb dpkg -c ~/packaging/classroom/classroom-fr*deb * Utilisons enfin lintian, qui permet de vérifier la qualité des .debs et des paquets source (par rapport à la debian policy) : lintian -Iv ~/packaging/classroom/classroom-fr*deb # pour le binaire lintian -Iv ~/packaging/classroom/classroom-fr*dsc # pour le paquet source Lintian permet de vérifier de nombreux points de votre paquet. Par exemple ici, on voit « I: classroom-fr source: debian-watch-file-is-missing », qui indique que nous pourrions ajouter un fichier debian/watch à notre packaging (ce fichier permet de vérifier la présence de nouvelles versions upstream et de les télécharger automatiquement via l'utilitaire « uscan »). Une méthode plus recommandable pour compiler vos paquets est l'utilisation de pbuilder, qui permet de créer les paquets dans un environnement minimal, ce qui limite le risque d'erreurs. Cepdendant nous ne l'avons pas détaillé ici, celà aurait été trop long. Le sujet sera peut-être évoqué dans un prochain cours ;)