====== Nano-manuel d'empaquetage façon Slackware ====== Par [[wiki:contributeurs:mushroom]]. Copyright © 2005, 2006, 2007, 2010 Sébastien Boillod Quiconque obtient une copie de ce document acquiert par la même le droit de reproduire, diffuser, modifier, traduire, adapter et/ou vendre celle-ci comme il l'entend, en plaçant les éventuelles contributions qu'il aura apportées sous les présents termes ou les termes de son choix. Cela tant qu'y figurent la mention copyright ci-dessus, cette autorisation et l'exonération de garantie ci-dessous. LES INFORMATIONS ET/OU LE CODE CONTENUS DANS CETTE OEUVRE NE SONT NULLEMENT GARANTIS MAIS SIMPLEMENT MIS À DISPOSITION « EN L'ÉTAT », DANS L'ESPOIR D'ÊTRE UTILES. VOUS ADMETTEZ EN LES UTILISANT AVOIR LES COMPÉTENCES REQUISES POUR PRENDRE TOUTES LES MESURES ET PRÉCAUTIONS NÉCESSAIRES À L'INNOCUITÉ DE CET USAGE, ET RECONNAISSEZ AINSI AGIR ENTIÈREMENT ET SANS RÉSERVE À VOS RISQUES ET PÉRILS : EN AUCUN CAS L'AUTEUR NE POURRA ÊTRE TENU POUR RESPONSABLE DES ÉVENTUELS DOMMAGES, TOUTES NATURES CONFONDUES, DIRECTS OU INDIRECTS, RÉSULTANT DE CETTE UTILISATION. Slackware est une marque déposée par Patrick Volkerding et Slackware Linux, Inc. Ce document et les informations qu'il contient n'émanent pas du projet Linux Slackware et n'ont donc aucun caractère officiel. ===== Avant-propos ===== Le qualificatif //Nano// pour pareil cachalot textuel pourra paraître singulier au lecteur qui n'aurait pas connu le //Petit manuel d'empaquetage façon Slackware//. En effet, ce dernier n'avait aussi de petit que le nom puisqu'il comportait en plus de celui-ci une partie présentant diverses clés pour personnaliser les scripts d'empaquetage, ainsi qu'un gros appendice sur la syntaxe //shell//. Ces parties ayant finalement été jugées superflues tant par leurs contenus (qui auraient nécessité une réelle maintenance) que par le surpoids qu'elles représentaient pour l'ensemble du texte, elles ont été retranchées((Pour la syntaxe //shell//, ''man bash'' ou plus court, ''man ash'' devraient vous en apprendre autant sinon plus)). D'où ce titre un peu incongru sentant la vieille boutade à plein nez (que voulez-vous, on ne se refait pas... ) ===== Introduction ===== Sous Slackware comme sous les autres distributions, il est bien rare de n'être pas un jour ou l'autre confronté au déroutant problème des sources et aux questions qui le suivent et le déclinent. //Comment procéder ? À quoi sert-donc cette curieuse opération que l'on nomme « compilation » ?// et surtout //Pourquoi (diable) cela ne marche-t-il pas ?// C'est à peu près comme cela que commence généralement le tortueux chemin qui mène d'une console syncopée d'erreurs à l'obtention de paquets s'intégrant parfaitement au reste du système. Ce qui va suivre vise tout simplement à vous faire gagner du temps par un exposé aussi explicite que possible des points à aborder pour réussir un paquet. Je tiens à préciser tout de suite que je ne suis nullement un spécialiste du ''bash'' ou de quelqu'autre langage de programmation. Tout ce que j'écris ici n'est que le résultat de lectures diverses (tutoriels, //man-pages//, forums,... ) et de longs tatônnements. Sa lecture ne requiert d'ailleurs que des connaissances basiques en ligne de commande : ''cd'', ''cp'', ''mv'', ''installpkg'', ''upgradepkg'', et bien sûr l'indispensable ''man'', voilà qui devrait amplement suffire pour suivre. Bien que le seul objet de ce manuel soit l'élaboration de paquets Slackware, l'exposé commencera par aborder des notions très générales sur la compilation des logiciels sous GNU/Linux. Il sera ainsi plus facile d'entrer dans les subtilités propres à la création des paquets de la Slackware en traitant la question des scripts de compilation (ou ''SlackBuild''s). ===== Obtenir un paquet ===== Nous avons défini notre objectif dans l'obtention de paquets Slackware, vaste sujet en vérité qui mérite donc un bon dégrossissage préalable. C'est pourquoi avant de travailler « l'orthodoxie » de nos paquets nous règlerons d'abord les questions permettant d'avoir un paquet « tout court ». ==== Les sources ==== === Qu'est-ce donc que les sources ? === Pour faire concis et rester au niveau de mes compétences : la résolution d'un problème de communication. Voici comment on peut poser ce problème : « Sachant que nous avons d'un côté un humain ne comprenant que des mots et des concepts souvent équivoques, et de l'autre une machine ne réagissant qu'à "0" (absence de courant) et "1" (présence de courant), comment les faire interagir pour qu'ils donnent des logiciels ? » La solution a consisté à prémâcher le travail de traduction pour la machine en simplifiant le langage humain. Ainsi naquirent les langages de programmation, caractérisés par un vocabulaire pauvre et une syntaxe rigide (en comparaison d'une langue naturelle), mais ayant l'immense avantage d'être relativement faciles à transposer automatiquement en "0" et "1" tout en restant maîtrisables par des humains. La partie humaine de cette solution est ce qu'on désigne par //sources//, soit un fichier texte redigé conformément à un (au minimum) langage de programmation. La partie machine, quant à elle, est appelée //binaire//, en référence au ''0|1'' qui compose la totalité du langage de cette dernière. Le passage de l'un à l'autre, enfin, s'effectue par une opération nommée //compilation//, qui traduit les sources en binaire. Les sources sont donc tout simplement le code tel qu'écrit et par les développeurs avant d'être compilé en code machine. Il convient d'ailleurs de signaler que leur disponibilité ou non pour l'utilisateur final est un des critères distingant les logiciels libres des logiciels propriétaires. Car à moins de parler couramment le "1" et le "0", il est pratiquement impossible de modifier un binaire. Avec les sources à l'inverse, pour peu qu'on maîtrise le langage de programmation dans lequel elles ont été écrites, toutes les adaptations et modifications sont envisageables. === Quel est l'intérêt de compiler des sources ? === Récapitulons : les sources sont du code, rédigé par un humain, appelé à être compilé pour être utilisable par la machine, et le libre permet de les obtenir. D'accord, ça a l'air très joli en théorie mais l'intérêt de la chose échappe encore. Pourquoi après tout ne pas se contenter des binaires disponibles dans notre chère Slackware ? Il n'y a effectivement rien d'impérieux à se lancer dans la compilation des sources, mais s'y mettre ouvre tout de même des perspectives intéressantes : * En premier lieu, elle permet de retravailler les paquets de la Slackware. Comme nous le verrons, les sources proposent souvent des options de compilation qui modulent les capacités des binaires obtenus. Il se peut donc parfaitement que Patrick Volkerding ((Fondateur et mainteneur de la Slackware.)), pour une raison ou une autre, en ait écartées que nous souhaiterions exploiter. Dans pareil cas une recompilation est le seul moyen de remédier à la chose (ou du moins de découvrir pourquoi les options en question n'ont pas été retenues). * En deuxième lieu, la Slackware a la particularité de n'être maintenue que par un seul homme. Il est donc bien évident qu'il doit faire un choix dans la gamme de binaires mis à disposition s'il veut pouvoir en assurer un maintien sérieux. Apprendre à compiler soi-même est alors un bon moyen (parfois le seul) pour utiliser des logiciels indisponibles dans la distribution officielle. * Enfin, compiler permet de participer à la vie du libre ((Il faut savoir que le libre est en fait entièrement basé sur l'échange des sources.)). Il existe en effet énormément de petits projets en développement qui n'attendent que des utilisateurs pour progresser et se faire connaître. Or ils ne peuvent souvent proposer guère plus que des sources. Refuser de se laisser intimider par la compilation permet alors de jouer les explorateurs en terre de développement, voir même de participer à la diffusion des logiciels qu'on aura appréciés en proposant le binaire ou la recette de compilation. Il existe probablement d'autres bonnes raisons pour se mettre à compiler les sources. Ne serait-ce que la curiosité et l'envie d'apprendre des choses nouvelles. Celles citées devraient cependant suffire pour se convaincre que l'enjeu en vaut la peine. === Où trouver les sources ? === Heureux celui qui a réalisé l'intérêt des sources, mais encore faut-il pour les compiler qu'il les trouve. En la matière il n'existe pas de règle incontournable, on peut toutefois donner quelques pistes selon que les sources recherchées font partie ou non de la distribution officielle. * si l'on veut récupérer les sources employées par Patrick Volkerding pour faire ses paquets, deux endroits sont à fouiller : * les CD #3 et #4 de la distribution qu'on a installée. C'est bête à dire, mais il n'y a pas plus simple pour trouver les sources de sa Slackware ; * les [[http://www.slackware.org/getslack/|miroirs Slackware]] : les sources sont contenues et rangées par familles de paquets dans le dossier ''/slackware-/source/'' de la version recherchée. * si l'on cherche des sources de logiciels non-proposés dans la Slackware officielle voici quelques bonnes adresses : * [[http://www.freshmeat.net|Freshmeat]] : un index référençant des milliers de projets de toutes tailles, classés par plate-formes, domaines, licences, etc... c'est un très bon moyen pour trouver les sites hébergeant les projets ; * [[http://www.sourceforge.net|Sourceforge]] : un hébergeur pour le développement libre sur lequel on trouve énormément de projets. * [[http://savannah.gnu.org|Savannah.gnu.org]] héberge les projets en rapport avec GNU (([[http://gnu.org|GNU's Not Unix]], projet fournissant au noyau Linux les programmes et bibliothèques nécessaires pour faire un système d'exploitation opérationnel.)). Il en existe également une version pour les projets libres non-affiliés,[[http://savannah.gnu.org|Savannah.non-gnu.org]] ; * [[http://tuxfamily.org|Tuxfamily]] : un hébergeur francophone de projets libres. Cette liste n'est bien évidemment pas exhaustive mais elle devrait néanmoins constituer un bon point de départ. Vos marque-pages se compléteront très bien tous seuls par la suite, au gré de vos découvertes. ==== La méthode de compilation « standard » ==== À présent que nous voici un peu mieux renseignés sur les sources, il est temps de traiter de la compilation à proprement parler. Pour commencer, il nous faut d'une part installer un compilateur et d'autre part trouver des sources à compiler. Pour ce qui est du compilateur, nous avons à disposition sous Slackware la //GNU Compiler Collection//, de très loin ce qui est le plus utilisé sous GNU/Linux. Le paquet est disponible dans le dossier ''d/'' de la Slackware, sous le nom de ''gcc'' ((Installer ''gcc-g%%++%%'' pour avoir un support du C%%++%% peut aussi se révéler une bonne idée.)). Pour ce qui est des sources on peut bien entendu prendre n'importe lesquelles, cependant nous avons choisi pour le reste de cette partie de nous pencher sur l'éditeur de texte [[http://bluefish.openoffice.nl/development.html|Bluefish]]. À l'heure où nous écrivons, la version la plus avancée est la ''1.0.5''. === Récupérer et préparer l'archive === Si nous avons esquissé une explication de ce qu'étaient les sources, nous n'avons en revanche rien dit sur la manière de les identifier. La plupart du temps les sources se présentent sous formes d'archives compressées par ''gzip'' ou ''bzip2'' : ''.tar.gz''((Il arrive que certaines archives compressées par gzip prennent la forme de ''.tgz''. Prenez garde à ne pas les confondre avec un binaire Slackware.)) ou ''.tar.bz2''. Parfois certains projets laissent le choix, si vous avez peu de place sur votre disque dur ou une connexion bas-débit, l'archive compressée par ''bzip2'' est à préférer car de taille plus réduite. Une fois l'archive téléchargée, la première chose à faire est de la décompresser en employant dans votre terminal préféré la commande ''tar'', la même qui a servi à sa compression. mushroom@packman:~$ tar xvfj bluefish-1.0.5.tar.bz2 [...] bluefish-1.0.5/TODO bluefish-1.0.5/config.guess bluefish-1.0.5/AUTHORS bluefish-1.0.5/Makefile.in bluefish-1.0.5/NEWS bluefish-1.0.5/README bluefish-1.0.5/config.sub bluefish-1.0.5/INSTALL bluefish-1.0.5/configure bluefish-1.0.5/COPYING bluefish-1.0.5/install-sh bluefish-1.0.5/aclocal.m4 bluefish-1.0.5/ChangeLog bluefish-1.0.5/configure.ac bluefish-1.0.5/INSTALL.Debian * Le ''x'' suivant la commande ''tar'' indique qu'il faut extraire le contenu de l'archive, le ''v'' demande de donner le maximum d'informations via la sortie standard (en l'occurrence la fenêtre du terminal), le ''f'' appelle l'archive et le ''j'' indique que celle-ci est a été compressée avec ''bzip2'' (si elle l'avait été par ''gzip'', on aurait dû mettre ''z'' à sa place ((Les versions modernes de ''tar'' semblent toutefois capables de détecter automatiquement le format de compression.)). Il ne reste plus qu'à entrer dans le dossier généré par la décompression à l'aide de la commande ''cd'' : mushroom@packman:~$ cd bluefish-1.0.5/ mushroom@packman:bluefish-1.0.5$ Les sources décompressées, il faut savoir que celles-ci ont toujours besoin de binaires extérieurs pour être compilées. Ces binaires sont ce qu'on appelle des « dépendances » et c'est grâce à leur action ou à leur contenu que la compilation va s'effectuer. La première chose à faire est de les identifier en consultant le fichier ''README'' contenu dans l'archive (parfois francisé en ''LISEZ-MOI'') : mushroom@packman:bluefish-1.0.5$ less README This is the Bluefish HTML editor. It has (among others) the following major features Customizable syntax highlighting based on Perl Compatible regular expressions, Multiple encodings support Wizards for startup, tables, frames, and others Dialogs for many HTML tags, with all their attributes User-customizable toolbar for quick access to often used functions A custom menu, specify your own tags or sets of code, and define your own dialogs Custom search and replace pattern support for the Custom menu Function reference browser, including reference files for PHP, HTML, CSS, PYTHON User customizable integration of many programs, including weblint, tidy, make Projects for quick access of frequently used sets of files Installation: See INSTALL file for information on how to install Bluefish [...] * La commande ''less'' a pour effet d'éditer le fichier en paginant la sortie. Cas fréquent, nous sommes ici renvoyés à un fichier ''INSTALL'', spécialement dédié aux questions d'installation (et donc de compilation). mushroom@packman:bluefish-1.0.5$ less INSTALL To install Bluefish from source: 1) get the required libraries (You will need the header files for these packages, usually these are packaged seperately with the prefix -dev, like libgtk2.0-dev or libpcre-dev): *libgtk2 (preferrably 2.2.2 or newer) *libpcre *gnome-vfs2 (Optional; for remote file handling) *aspell (Optional; for spell checking) *grep and find are required to use the Advance Open function 2) run ./configure --help for information about possible options. (This step is usually not required) 3) configure and compile ./configure [options-you-like-most-here] make 4) install everything su make install [...] Nous avons de la chance car l'''INSTALL'' de ''Bluefish'' est riche en informations. Ainsi nous pouvons connaître les dépendances requises et nous voyons que nous sommes en présence d'une procédure de compilation très classique (quasi-standard) passant par la séquence « ''configure''/''make''/''make install'' ». La liste des dépendances n'est jamais exhaustive dans la mesure où elles s'étalent sur plusieurs générations ((L'image des générations est pertinente la plupart du temps, mais pas toujours, car il existe des dépendances dites « circulaires » s'engendrant l'une l'autre. Un compilateur, par exemple, a besoin d'un compilateur pour être compilé.)) : **z** nécessite que **y** soit installé, qui nécessite lui même **x**,... Les ancêtres se situant toujours dans les couches profondes de GNU/Linux, ils sont souvent considérés comme allant de soi. En général ne sont donnés que les parents et (parfois) les grands-parents du logiciel. Il ne faut donc pas s'étonner si même après avoir installé les paquets requis la compilation échoue à trouver certains éléments. Le tout est en fait de savoir comment identifier les dépendances manquantes. checking for gnome-vfs >= 2.2... no checking for gnome-vfs >= 2.6... no checking for libgnomeui >= 2.6... no checking for pcre-config... no configure: error: pcre-config not found please install libpcre3-dev or similar mushroom@packman:bluefish-1.0.5$ Dans l'exemple de sortie en erreur ci-dessus, il nous est demandé ''pcre-config'' (en général, les messages d'erreur contenant '' not found'' relèvent d'un problème de dépendance). La première question qui doit venir à l'esprit est « La dépendance manquante est-elle disponible dans la Slackware ? », elle économisera du temps et préviendra pas mal de problèmes. Pour répondre à cette question, deux ressources sont à notre disposition : * Le [[http://www.slackware.org/pb/|gestionnaire de paquets du site Slackware]] : il suffit de taper le nom de la dépendance dans le moteur de recherche, et celui-ci indiquera dans quel paquet elle se trouve, si toutefois elle est bien disponible dans la Slackware ((Indiquez bien « //file name// » dans le deuxième champ de recherche, autrement celle-ci ne portera que sur les noms des paquets.)). * Les fichiers ''MANIFEST'' : situés dans les répertoires ''slackware/'' des CD#1 et #2, ils listent le contenu des paquets de leur CD respectif. Ils sont compressés par ''bzip2''. Le mieux est généralement de les copier sur le disque dur (ici nous avons mis le ''MANIFEST'' du premier CD dans notre dossier utilisateur). Il vous suffit ensuite d'utiliser la commande suivante où '''' sera le nom de la dépendance recherchée : bzcat ~/MANIFEST.bz2 | sed "{/\|Package:/p}" -n | less * La commande ''bzcat'' affiche le contenu du fichier compressé par ''bzip2'', puis l'envoie à la commande ''sed''. Celle-ci ne retiendra que les lignes contenant '''' ou ''Package:'' qu'elle transmettra à ''less'' que nous venons de voir. Voici un exemple avec ''pcre-config'' : mushroom@packman:~$ bzcat ~/MANIFEST.bz2 | sed "{/pcre-config\|Package:/p}" -n | less [...] || Package: ./l/netpbm-10.18.12-i486-1.tgz || Package: ./l/pango-1.8.2-i486-1.tgz || Package: ./l/pcre-6.4-i486-1.tgz -rwxr-xr-x root/bin 1192 2005-09-12 17:25:14 usr/bin/pcre-config || Package: ./l/pilot-link-0.11.8-i486-2.tgz || Package: ./l/popt-1.7-i386-1.tgz [...] De la présente sortie, nous pouvons conclure que ''pcre-config'' est dans le paquet ''./l/pcre-6.4-i486-1.tgz'' Ici nous avons donc trouvé ce que nous cherchions dans le paquet ''pcre'' (répertoire ''l/''), il n'en va hélas pas toujours ainsi. Même si la Slackware est plutôt bien pourvue pour satisfaire les dépendances des logiciels hors-distribution, il arrive en effet qu'il faille compiler certaines dépendances. Pour trouver celles-ci, le plus simple est de chercher sur le site du logiciel car il est bien rare qu'il n'y ait pas de lien vers les sites hébergeant le développement de ses dépendances. Si cette voie échoue, il ne restera alors plus qu'à recourir aux moyens que nous avons déjà évoqués (cf. [[#où_trouver_les_sources_?|Où trouver les sources ?]]). === Configurer les sources === Les questions liées à la préparation de l'archive étant théoriquement((Limitation de la liste des dépendances annoncées oblige, les deux phases se chevauchent en effet souvent dans les faits)) réglées nous pouvons aborder celle de la configuration des sources. La configuration des sources, dans la grande majorité des cas, est assurée via un script exécutable contenu dans celles-ci et nommé ''configure''. Son rôle est double : d'une part il permet à l'utilisateur de moduler les caractéristiques du binaire final, d'autre part il collecte des informations sur le système pour connaître son type, l'emplacement des binaires requis, le compilateur utilisé, etc. afin de paramétrer la compilation. Avec un peu d'expérience, vous remarquerez que certaines options et syntaxes reviennent souvent d'un ''configure'' à l'autre, il n'en demeure pas moins qu'un ''configure'' est toujours propre aux sources qu'il configure. Regardons un peu plus en détail celui de ''Bluefish'' dans ses éléments les plus communément rencontrés((Les numéros de lignes, ajoutés ici pour des besoins de l'explication, n'apparaissent normalement pas à l'écran.)) : mushroom@packman:bluefish-1.0.5$ ./configure --help 1 `configure' configures this package to adapt to many kinds of systems. 2 3 Usage: ./configure [OPTION]... [VAR=VALUE]... 4 5 To assign environment variables (e.g., CC, CFLAGS...), specify them as 6 VAR=VALUE. See below for descriptions of some of the useful variables. 7 8 Defaults for the options are specified in brackets. [...] 20 21 Installation directories: 22 --prefix=PREFIX install architecture-independent files in PREFIX 23 [/usr/local] 24 --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX 25 [PREFIX] 26 27 By default, `make install' will install all the files in 28 `/usr/local/bin', `/usr/local/lib' etc. You can specify 29 an installation prefix other than `/usr/local' using `--prefix', 30 for instance `--prefix=$HOME'. 31 * Dans l'invite de commande, ''./'' indique que le fichier est dans le répertoire courant et l'option ''--help'' demande des informations quant à l'usage de ce ''configure'' . Cette option est disponible dans la plus grande part des fichiers de cet type ; * L'option ''--prefix='' (l. 22) est sans doute l'option la plus communément utilisée avec les ''configure''. Elle permet de définir dans quel dossier sera installé le binaire final. En règle générale les logiciels sont paramétrés par défaut pour s'installer dans ''/usr/local/''. C'est un choix compréhensible dans la mesure où ''/usr/local'' est justement prévu pour accueillir les logiciels hors-distribution. Il faut cependant prendre garde car certains éléments ne sont pas toujours localisés par le système lorsqu'ils sont dans ce répertoire. Cela peut poser problème, notamment si ces éléments sont requis en tant que dépendances par d'autres logiciels. C'est pourquoi on peut lui préférer le répertoire ''/usr/'', traditionnellemnt dévolu aux logiciels venant avec la distribution. 32 For better control, use the options below. 33 34 Fine tuning of the installation directories: 35 --bindir=DIR user executables [EPREFIX/bin] 36 --sbindir=DIR system admin executables [EPREFIX/sbin] 37 --libexecdir=DIR program executables [EPREFIX/libexec] 38 --datadir=DIR read-only architecture-independent data [PREFIX/share] 39 --sysconfdir=DIR read-only single-machine data [PREFIX/etc] 40 --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] 41 --localstatedir=DIR modifiable single-machine data [PREFIX/var] 42 --libdir=DIR object code libraries [EPREFIX/lib] 43 --includedir=DIR C header files [PREFIX/include] 44 --oldincludedir=DIR C header files for non-gcc [/usr/include] 45 --infodir=DIR info documentation [PREFIX/info] 46 --mandir=DIR man documentation [PREFIX/man] 47 * Les options de préfixation, lignes 34 à 46, fonctionnent comme ''--prefix='', à cette différence qu'elles paramètrent le répertoire d'installation d'un élément précis du logiciel. Par exemple, si le logiciel dans son entier est préfixé pour s'installer dans ''/usr/local'', ''--sysconfdir=/etc'' permet d'installer les élements du logiciel concernant la configuration système dans ''/etc'' au lieu de ''/usr/local/etc''. 48 Program names: 49 --program-prefix=PREFIX prepend PREFIX to installed program names 50 --program-suffix=SUFFIX append SUFFIX to installed program names [...] 53 System types: 54 --build=BUILD configure for building on BUILD [guessed] 55 --host=HOST cross-compile to build programs to run on HOST [BUILD] 56 57 Optional Features: 58 --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) 59 --enable-FEATURE[=ARG] include FEATURE [ARG=yes] [...] 89 90 Optional Packages: 91 --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] 92 --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) [...] * Les options lignes 49 et 50 servent à ajouter du texte avant ou après le nom du programme. Elles sont utiles lorsque, par exemple, on a besoin d'installer sur une machine un même logiciel sous des versions différentes ; * L'option ''--build='' (l. 54) permet d'indiquer l'architecture du système sur lequel est compilé le programme afin que le compilateur puisse l'optimiser à partir de celle-ci. L'option ''--host='' (souvent appelée ''--target=''), ligne 55, quant à elle, sert à spécifier l'architecture du système de destination du futur binaire((Comme nous le verrons plus tard, ces variables peuvent être réglées directement auprès du compilateur, cf. [[#En tête : définition des variables|En tête , définition des variables]].)). Il existe beaucoup de ''configure'' qui, à l'instar de celui-ci (« //guessed// » signifie « déduit »), déterminent automatiquement l'architecture du système sur lequel ils sont lancés et ordonnent une optimisation pour et à partir de celle-ci ; * Les options ''--disable-'' et ''--enable-'' (l. 58-59) sont très communes. Elle servent à désactiver ou à activer le support de certaines options par le logiciel. Cela peut être utilisé lorsqu'on ne veut pas installer certaines dépendances requises du seul fait d'un support ; * Les options lignes 91 et 92 sont proches des ''--disable/enable-'' mais elles visent une dépendance plutôt qu'un support. Par exemple, elles sont utiles lorsqu'on a une une dépendance optionnelle installée sur son système mais qu'on ne veut pas que le logiciel en tienne compte (les ''configure'' ont souvent tendance à utiliser tout ce qui leur tombe sous la main pour paramétrer la compilation). 117 Some influential environment variables: 118 CC C compiler command 119 CFLAGS C compiler flags 120 LDFLAGS linker flags, e.g. -L if you have libraries in a 121 nonstandard directory 122 CPPFLAGS C/C%%++%% preprocessor flags, e.g. -I if you have 123 headers in a nonstandard directory 124 CPP C preprocessor 125 126 Use these variables to override the choices made by `configure' or to help 127 it to find libraries and programs with nonstandard names/locations. 128 * Ces options permettent de préciser les paramètres de compilation. Entre autres, on peut ainsi préciser le compilateur utilisé, le degré, la portée (faire un binaire compatible ou non avec des architectures proches de celle utilisée) et le sens des optimisations (par exemple, faire un binaire le plus petit possible). Pour ce qui est des deux options ''LDFLAGS'' et ''CPPFLAGS'', elles aident le compilateur à s'y retrouver sur des systèmes un peu exotiques. La liste des options proposées peut paraître à première vue longue et difficile à appréhender. On aurait dans une large mesure tort car il faut bien voir que toutes ces options sont d'abord conçues pour ceux qui maintiennent des distributions. Dans le cadre d'un empaquetage « artisanal » on n'a souvent à manier guère plus que ''--prefix='', comme ici : mushroom@packman:bluefish-1.0.5$ ./configure --prefix=/usr/local/ checking for gcc... gcc checking for C compiler default output file name... a.out [...] checking for a BSD-compatible install... /usr/bin/ginstall -c checking build system type... i686-pc-linux-gnu checking host system type... i686-pc-linux-gnu [...] checking for GNU gettext in libc... yes checking for dcgettext... yes checking for msgfmt... /usr/bin/msgfmt checking for gmsgfmt... /usr/bin/msgfmt 1 checking for xgettext... /usr/bin/xgettext checking for bison... no checking for catalogs to be installed... bg cs da de es fi fr hu it ja [...] checking for msgmerge... /usr/bin/msgmerge checking for gettext in -lintl... no configure: creating ./config.status config.status: creating Makefile config.status: creating icons/Makefile config.status: creating src/Makefile 2 config.status: creating po/Makefile config.status: creating data/Makefile config.status: creating src/config.h config.status: executing default-1 commands ----------- If you like this program, please let me know and send me a postcard and tell me what city/country you're from: Olivier Sessink Thorbeckestraat 470 3 6702 CJ Wageningen The Netherlands ----------- * Ce ''configure'' teste si les ''gettext-tools'' sont présents. Ceux-ci sont couramment utilisés pour internationnaliser les logiciels. Si vous souhaitez que les logiciels que vous compilez comportent une version française (quand elle est disponible, comme ici où la ligne ''checking for catalogs to be installed'' comporte ''fr''), installez le paquet ''gettext-tools'' contenu dans le répertoire ''d/'' de la Slackware ; * Une fois tous les tests effectués, le ''configure'' crée les ''Makefile''s, fichiers contenant les instructions pour la compilation ; * Il arrive que certains ''configure'' se terminent par un petit résumé des options retenues pour la compilation. Ce n'est pas le cas ici mais nous avons tout de même droit à un gentil clin d'oeil. Soulignons pour finir sur les ''configure'' qu'il arrive hélas que certaines sources, anciennes ou avec une procédure de compilation inhabituelle, n'en contiennent pas. Dans pareil cas il convient de lire attentivement le ''README'' pour saisir comment la prise en main par l'utilisateur final a été pensée par les développeurs et agir en conséquence (en général cela passe par l'édition d'un ''Makefile''). === Compiler et installer le binaire === Une fois les sources configurées avec succès, nous pouvons ordonner leur compilation via la commande ''make'' (présente dans le paquet make du répertoire ''d/'') : mushroom@packman:bluefish-1.0.5$ make cd po/ && make all; make[1]: Entering directory `/home/mushroom/bluefish-1.0.5/po' [...] /usr/bin/msgfmt fr.po -o fr.gmo [...] make[1]: Leaving directory `/home/mushroom/bluefish-1.0.5/po' make[1]: Entering directory `/home/mushroom/bluefish-1.0.5/src' gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DGNULOCALEDIR=\"/usr/local/share/locale\" -DLOCALE_ALIAS_PATH=\"/usr /local/share/locale:.\" -DPKGDATADIR=\"/usr/local/share/bluefish/\" -DHAVE_CONFIG_H -g -O2 -Wall -pipe -DXTHREADS - D_REENTRANT -DXUSE_MTSAFE_API -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/11R6/include -I/usr/include /atk-1.0 -I/usr/include/pango-1.0 -I/usr/include/freetype2 -I/usr/include/freetype2/config -I/usr/include/glib-2.0 -I /usr/lib/glib2.0/include -c -o about.o about.c [...] The bluefish binary is succesfully created make[1]: Leaving directory `/home/mushroom/bluefish-1.0.5/src' make[1]: Entering directory `/home/mushroom/bluefish-1.0.5/data [...] make[1]: Leaving directory `/home/mushroom/bluefish-1.0.5/data Voici le flux grandement tronqué de ce que vous devriez obtenir avec ''Bluefish''. À ce stade, si le ''configure'' a oublié de vérifier certains éléments, il peut encore se produire des erreurs liées à des problèmes de dépendances. Néanmoins, si votre système ne fait pas dans le minimalisme, cela est assez rare car les éléments alors oubliés sont souvent très courants. La compilation terminée, il va nous falloir installer le binaire. La commande standard d'installation, ''make install'', a pour effet de mettre les fichiers compilés dans le répertoire préfixé, pour ce qui nous concerne ''/usr/local''. Outre le fait que nous n'avons pas les droits (seul le superutilisateur peut écrire dans ''/usr/local''), nous voulons faire un paquet en préalable à toute installation. C'est pourquoi il va d'abord falloir rediriger l'installation vers un dossier temporaire : un dossier différent de la destination finale et sur lequel nous aurons les droits nécessaires. Pour ce, il existe la variable ''DESTDIR=''((Le nom de variable ''DESTDIR'' est un nom communément employé qui devrait être reconnu la plupart du temps. Cependant rien n'empêche que la variable porte un autre nom.)) qui permet de moduler ''make install'' : mushroom@packman:bluefish-1.0.5$ make install DESTDIR=/home/mushroom/bluefish-pkg /usr/bin/ginstall -c -d -m 755 /home/mushroom/bluefish-pkg/usr/share/pixmaps /usr/bin/ginstall -c -m 644 inline_images/bluefish_icon1.png /home/mushroom/bluefish-pkg/usr/share/pixmaps/bluefish- icon.png [...] make[1]: Entering directory `/home/mushroom/bluefish-1.0.5/src' /usr/bin/ginstall -c -d -m 755 /home/mushroom/bluefish-pkg/usr/local//bin /usr/bin/ginstall -c -s -m 755 ./bluefish /home/mushroom/bluefish-pkg/usr/local//bin/bluefish [...] make[1]: Leaving directory `/home/mushroom/bluefish-1.0.5/data' La variable ''DESTDIR='' a pour effet de simuler une racine. Elle crée le dossier temporaire demandé((La plupart du temps, car parfois il faut créer celui-ci au préalable.)) avant d'y installer les fichiers comme si celui-ci était la racine du système. Notre binaire est à présent prêt à être empaqueté, ce qui marque la fin de cette sous-section consacrée à la méthode de compilation standard. Tout ou presque de ce qui a été vu dans celle-ci est réutilisable sous n'importe quel autre système GNU/Linux. Cela étant dit, il est maintenant temps de commencer notre incursion dans la dimension Slackware à proprement parler en examinant son outil d'empaquetage : ''makepkg''. ==== L'empaqueteur Slackware : makepkg ==== Comme ses petits frères((À savoir ''installpkg'', ''upgradepkg'', ''removepkg'' et ''explodepkg''.)) partage l'esprit //KISS//((//Keep It Simple, Stupid !//, soit « Fais-donc simple, idiot ! »)) des ''pkgtools'' et demeure un outil fort basique dans son utilisation. Pour s'en rendre compte, nous allons poursuivre notre exemple avec ''Bluefish'' en allant au plus simple, car après tout l'objectif de cette partie est d'obtenir un paquet, pas un //beau// paquet. Tout d'abord il faut se placer dans le dossier racine des fichiers à empaqueter, soit le répertoire temporaire d'installation défini par ''DESTDIR'' : mushroom@packman:bluefish-1.0.5$ cd /home/mushroom/bluefish-pkg/ mushroom@packman:bluefish-pkg$ Ensuite, nous passons en superutilisateur : mushroom@packman:bluefish-pkg$ su Mot de passe: root@packman:bluefish-pkg# Enfin, nous lançons ''makepkg'' suivi du ''.tgz'' que nous souhaitons attribuer au paquet : root@packman:bluefish-pkg# makepkg bluefish-1.0.5-mypkg.tgz Slackware package maker, version 2.1. Searching for symbolic links: No symbolic links were found, so we won't make an installation script. You can make your own later in ./install/doinst.sh and rebuild the package if you like. This next step is optional - you can set the directories in your package to some sane permissions. If any of the directories in your package have special permissions, then DO NOT reset them here! Would you like to reset all directory permissions to 755 (drwxr-xr-x) and directory ownerships to root.root ([y]es, [n]o)? Nous sommes tout d'abord informés qu'aucun lien symbolique n'a été trouvé dans le dossier et qu'il n'y a donc rien à faire les concernant. Autrement, on nous aurait demandé s'il fallait les rétablir après l'installation, ce qui aurait été fait grâce à un script prévu à cet effet, généré par ''makepkg'' et exécuté après l'installation des fichiers (cf. [[#Appendice A : Utilisation des scripts d'installation|Appendice A , Utilisation des scripts d'installation]]). On nous demande ensuite si l'on veut formater les permissions des répertoires. Le formatage consiste à attribuer tous les fichiers au superutilisateur et à son groupe en permettant à tous de les voir et de les exécuter mais à lui seul d'écrire dedans (tapez ''man chmod'', pour un complément d'information). Comme nous n'avons pas défini de permissions spéciales, nous allons répondre « oui » en appuyant sur la touche **[y]**. Le mode d'accès de `.' a été modifié à 0755 (rwxr-xr-x). Le mode d'accès de `./usr' a été modifié à 0755 (rwxr-xr-x). Le mode d'accès de `./usr/share' a été modifié à 0755 (rwxr-xr-x). Le mode d'accès de `./usr/share/pixmaps' a été modifié à 0755 (rwxr-xr-x). [...] Changement de propriétaire de `.' vers root:root Changement de propriétaire de `./usr' vers root:root Changement de propriétaire de `./usr/share' vers root:root Changement de propriétaire de `./usr/share/pixmaps' vers root:root [...] Creating tar file bluefish-1.0.5-mypkg.tar... ./ usr/ [...] usr/local/share/bluefish/ usr/local/share/bluefish/bluefish_splash.png usr/local/share/bluefish/icon_c.png [...] usr/local/share/mime/ usr/local/share/mime/packages/ usr/local/share/mime/packages/bluefish.xml usr/local/share/mime-info/ usr/local/share/mime-info/bluefish.mime usr/local/share/mime-info/bluefish.keys usr/local/bin/ usr/local/bin/bluefish tar-1.13: bluefish-1.0.5-mypkg.tar is the archive; not dumped Gzipping bluefish-1.0.5-mypkg.tar... Renaming bluefish-1.0.5-mypkg.tar.gz to bluefish-1.0.5-mypkg.tgz... Package creation complete. Comme convenu, les permissions sont changées puis les répertoires sont attribués au superutilisateur. Ensuite ceux-ci et leur contenus sont archivés par la commande ''tar'' puis l'archive est à son tour compressée par ''gzip'', exactement de la même manière que pour des sources. Seul petit changement (purement formel), celle-ci troque finalement son extension ''tar.gz'' contre le ''.tgz'' caractéristique des paquets de la Slackware. Nous voulions un paquet, et bien nous en avons un, vous pouvez vous en rendre compte de suite via la commande ''installpkg bluefish-1.0.5-mypkg.tgz'' : l'installation se déroule parfaitement. À tel point d'ailleurs que c'en est déconcertant, car quoi ! Est-ce donc ça l'empaquetage Slackware ? une méthode de compilation des plus banales suivie d'un archivage à la sauvette ? Et bien, oui et non... Oui tout d'abord parce que malgré une procédure rudimentaire notre paquet fonctionne. Non ensuite, car c'est un travail certes fonctionnel mais assez grossier, ce qui sied quand même fort mal à une Slackware. En fait, l'esprit Slackware consiste souvent à affiner les techniques tout en les laissant sous le contrôle de l'utilisateur final : permettre à l'humain de bien faire plutôt que laisser la technique le reléguer en bout de chaîne. Il est donc normal que la Slackware autorise des choses aussi inélégantes que ce que nous venons d'installer (''removepkg bluefish-1.0.5-mypkg.tgz'' devrait remédier à la chose), il manque juste un humain entre les sources et le paquet. C'est en effet à lui qu'est laissé le soin de donner aux outils leur pleine mesure, et c'est à cet objectif que tentera de contribuer le mieux possible la seconde partie de ce manuel. ===== Le conditionnement Slackware ===== Alors que la précédente partie visait à donner des bases pour réussir à construire un binaire, la présente traite la question des scripts de compilation Slackware. Pour ce, nous nous baserons sur ce que fait Patrick Volkerding pour compiler les binaires de sa distribution. Comme nous l'avons vu dans la précédente section, la qualité des paquets Slackware est totalement liée à celle de ce qui est transmis à son empaqueteur. Tout le travail d'affinement et de préparation doit donc être effectué avant qu'un quelconque contenu ne soit fourni à ''makepkg''. Ainsi défini l'objectif paraît encore très nébuleux, car on voit mal par quel bout aborder la chose et surtout sur quel critère tracer un chemin un tant soit peu droit pour l'atteindre. Heureusement, une fois encore nous ne sommes pas laissés à nous-mêmes : « Aide-toi et ta Slack t'aidera », pourrions-nous même dire. Si une personne doit être au fait de ce qu'est un paquet correctement formé, c'est bien le concepteur de la Slackware, Patrick Volkerding. Or, non content de mettre à disposition ses binaires, il nous a également laissé la recette de compilation pour chacun. En effet, si vous jetez un oeil dans les différents dossiers contenant les sources (cf. [[#Où trouver les sources ?|Où trouver les sources ?]]), vous verrez qu'ils comportent tous un fichier ''.SlackBuild''. En éditant ceux-ci, vous constaterez vite qu'ils partagent tous une trame commune, soit une base de travail solide pour nos propres recettes. Pour la suite de cette partie, nous avons choisi de nous pencher sur le ''SlackBuild'' de ''sed'', un éditeur de texte non-interactif (//stream editor//). Deux raisons à ce choix : d'une part ce ''SlackBuild'' est à peu près générique (pas de //patch//, ni d'ajouts inhabituels), d'autre part ''sed'' est requis par le système, ce qui garantit une certaine pérennité à l'exemple. Voici le texte complet du ''SlackBuild'' de ''sed''. Les sous-sections à venir en extrairont des fragments pour les commenter. Cela vous permettra, à l'aide des numéros de ligne, de vous reporter à tout moment au texte complet pour replacer le fragment concerné dans son contexte. 1 #!/bin/sh 2 CWD=`pwd` 3 PKG=/tmp/package-sed 4 5 VERSION=4.0.9 6 ARCH=${ARCH:-i486} 7 BUILD=2 8 9 if [ "$ARCH" = "i386" ]; then 10 SLKCFLAGS="-O2 -march=i386 -mcpu=i686" 11 elif [ "$ARCH" = "i486" ]; then 12 SLKCFLAGS="-O2 -march=i486 -mcpu=i686" 13 elif [ "$ARCH" = "s390" ]; then 14 SLKCFLAGS="-O2" 15 elif [ "$ARCH" = "x86_64" ]; then 16 SLKCFLAGS="-O2" 17 fi 18 19 rm -rf $PKG 20 mkdir -p $PKG 21 cd /tmp 22 rm -rf sed-$VERSION 23 tar xzvf $CWD/sed-$VERSION.tar.gz 24 cd sed-$VERSION 25 chown -R root.root . 26 find . -perm 777 -exec chmod 755 {} \; 27 find . -perm 664 -exec chmod 644 {} \; 28 CFLAGS="$SLKCFLAGS" \ 29 ./configure \ 30 --prefix=/usr \ 31 $ARCH-slackware-linux 32 make 33 make install DESTDIR=$PKG 34 mkdir -p $PKG/bin 35 mv $PKG/usr/bin/sed $PKG/bin 36 ( cd $PKG/usr/bin ; ln -sf /bin/sed . ) 37 chown -R root.bin $PKG/usr/bin $PKG/bin 38 ( cd $PKG 39 find . | xargs file | grep "executable" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null 40 find . | xargs file | grep "shared object" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null 41 ) 42 mkdir -p $PKG/usr/doc/sed-$VERSION 43 cp -a \ 44 ANNOUNCE AUTHORS BUGS COPYING* INSTALL NEWS README README.boot THANKS TODO \ 45 $PKG/usr/doc/sed-$VERSION 46 gzip -9 $PKG/usr/man/man?/*.? 47 rm -f $PKG/usr/info/dir 48 gzip -9 $PKG/usr/info/* 49 mkdir -p $PKG/install 50 cat $CWD/slack-desc > $PKG/install/slack-desc 51 52 cd $PKG 53 makepkg -l y -c n ../sed-$VERSION-$ARCH-$BUILD.tgz ==== Préambule : Qu'est-ce qu'un SlackBuild ? ==== Un ''SlackBuild'' n'est rien d'autre qu'un script shell, certes appliqué à la compilation, mais ne se différenciant pas fondamentalement des autres scripts. C'est à dire, hormis quelques fonctionnalités très spécifiques, qu'il ne fait que passer les commandes qu'il contient au système, comme le ferait l'utilisateur via son terminal. Vous pourriez donc, moyennant quelques remaniements mineurs, donner ces commandes une à une dans un terminal, vous obtiendriez au final le même résultat. Nous allons tenter dans ce qui suit de découper ce ''SlackBuild'' en mettant en évidence ses différentes phases. Nous ne nous attarderons donc pas sur les questions de syntaxe ''bash'', sauf pour ce qui apparaît comme fondamental. ==== En tête : définition des variables ==== 1 #!/bin/sh 2 CWD=`pwd` 3 PKG=/tmp/package-sed 4 5 VERSION=4.0.9 6 ARCH=${ARCH:-i486} 7 BUILD=2 8 9 if [ "$ARCH" = "i386" ]; then 10 SLKCFLAGS="-O2 -march=i386 -mcpu=i686" 11 elif [ "$ARCH" = "i486" ]; then 12 SLKCFLAGS="-O2 -march=i486 -mcpu=i686" 13 elif [ "$ARCH" = "s390" ]; then 14 SLKCFLAGS="-O2" 15 elif [ "$ARCH" = "x86_64" ]; then 16 SLKCFLAGS="-O2" 17 fi - La première ligne du script((On appelle aussi cela le « //shebang !// »)) indique le shell((« //coquille// » en anglais.)), l'interpréteur de commande dans lequel doit être exécuté le script. Elle est présente sur tout script destiné à être exécutable. Dans le cas présent il s'agit du //Bourne Again SHell//((À moins que /bin/sh pointe sur autre que ''/bin/bash'' chose chez vous.)). En //shell// une variable se définit comme suit : ''=''. Pour l'appeler on utilise le symbole « $ » accolé au début son nom : ''$'' (ou ''${}'' dans sa version étendue). Elle est alors immédiatement remplacée par sa définition (on dit qu'elle est « expansée »). Nous avons ici, lignes 2 à 7, cinq variables de définies. * ''CWD'' qui récupère via la commande ''pwd'' le chemin (absolu) du répertoire où est exécuté le script ; * ''VERSION'' qui définit la version du logiciel qu'on veut compiler ; * ''PKG'' qui indique le répertoire temporaire où mettre le binaire avant de l'empaqueter (cf. [[#Compiler et installer le binaire|Compiler et installer le binaire]]) ; * ''ARCH'' qui donne l'architecture pour lequel est compilé le paquet. Par défaut (valeur introduite par << :- >> )Patrick Volkerding optimise les paquets pour une construction sur un 486 ; * ''BUILD'' qui correspond au numéro de compilation. Ici c'est la deuxième fois que le paquet a été compilé. Cela est utile lorsqu'on modifie un paquet sans que le logiciel compilé ait changé de version. - Lignes 9 à 17 suit une série de tests qui va déterminer les ''FLAGS'' d'optimisation ([[#Configurer les sources|Configurer les sources]]). Dans notre cas ''$ARCH'' renvoie "i486", la série de test s'arrêtera par conséquent au deuxième test (l. 11). ''SLKCFLAGS'', sixième variable définie ici, prendra donc la valeur ''-O2 -march=i486 -mcpu=i686''((Cette syntaxe fonctionne avec la branche 3.3.x de gcc. Pour les branches plus récentes, ''--mcpu=i686'' a été remplacé par ''--mtune=i686''.)), soit une optimisation de niveau 2 (''-O2'') à partir d'un ''486'' pour une architecture ''i686'' (regroupant, notamment, la série maintenant très courante des pentium4 et assimilés). ==== Initialisation et compilation ==== 19 rm -rf $PKG 20 mkdir -p $PKG 21 cd /tmp 22 rm -rf sed-$VERSION 23 tar xzvf $CWD/sed-$VERSION.tar.gz 24 cd sed-$VERSION 25 chown -R root.root . 26 find . -perm 777 -exec chmod 755 {} \; 27 find . -perm 664 -exec chmod 644 {} \; 28 CFLAGS="$SLKCFLAGS" \ 29 ./configure \ 30 --prefix=/usr \ 31 $ARCH-slackware-linux 32 make 33 make install DESTDIR=$PKG - On initialise en ordonnant la suppression du répertoire d'installation temporaire (l. 19). L'argument ''-f'' (« //force// ») passé à la commande ''rm'' fera qu'aucune erreur ne sera retournée si le répertoire n'existe pas. Initialiser de la sorte permet de s'assurer, entre autres, que le répertoire ne contiendra rien d'autre que ce qui sera généré par le script. Cela fait, on crée le répertoire temporaire avec la commande ''mkdir'' (l. 20). Le ''-p'' placé en argument demande de créer tous les répertoires indiqués dans le chemin s'ils n'existent pas déjà ; - On passe dans le répertoire ''/tmp'' (dédié, comme son nom l'indique plus ou moins, à ce qui est temporaire) à l'aide de la commande ''cd''. On initialise à nouveau (l. 21), mais cette fois c'est le répertoire des sources qui est visé. Ensuite on décompacte l'archive en partant du principe que celle-ci est dans le répertoire courant : souvenez-vous de ce à quoi correspond ''$CWD'' (pour les options de ''tar'', cf. [[#Récupérer et préparer l'archive|Récupérer et préparer l'archive]]). Cela fait, on entre dans le dossier ainsi généré((Patrick Volkerding part du principe que le dossier résultant de l'archive contenant les sources sera de la forme ''-''. Cela est (très) généralement le cas, néanmoins techniquement rien n'interdit qu'il en soit autrement, même quand le nom de l'archive respecte cette forme standard.)) (l. 24) ; - Une fois dans le répertoire source, on initialise les permissions. Le dossier entier est attribué au superutilisateur et à son groupe via la commande ''chown'' (l. 25). Le ''-R'' en argument indique que la commande est récursive : tout le contenu du dossier sera modifié. Ensuite on ordonne à la commande ''find'' (l. 26-27) de rechercher tout ce qui est en permission ''777'' (droit de lecture, d'écriture et d'exécution pour tous) pour le transformer en ''755'' (droit d'écriture uniquement pour l'utilisateur, en l'occurence ''root''), et tout ce qui est en ''664'' (droits de lecture et d'écriture pour l'utilisateur et le groupe, lecture seule pour les autres) en ''644'' (lecture seule pour tous hormis l'utilisateur). Cela tient au fait que le dossier source ne sera pas forcément détruit après la compilation (pas par le script en tout cas), il est donc bon que seul le superutilisateur soit autorisé à y écrire ; - On affecte aux ''CFLAGS'' le contenu de la variable ''SLKCFLAGS'' (l. 28), puis on passe les paramètres au ''configure'' (l. 29-31). La ligne ''$ARCH-slackware-linux'' ne correspond pas à une commande, elle fournit juste une information sur la distribution et l'architecture de compilation, information que le binaire portera en lui (pour les autres lignes, cf. [[#Configurer les sources|Configurer les sources]]). - Lignes 32-33, on procède à la compilation et à l'installation temporaire (cf. [[#Compiler et installer le binaire|Compiler et installer le binaire]]). ==== Remaniements et affinements ==== 34 mkdir -p $PKG/bin 35 mv $PKG/usr/bin/sed $PKG/bin 36 ( cd $PKG/usr/bin ; ln -sf /bin/sed . ) 37 chown -R root.bin $PKG/usr/bin $PKG/bin 38 ( cd $PKG 39 find . | xargs file | grep "executable" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null 40 find . | xargs file | grep "shared object" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null 41 ) 42 mkdir -p $PKG/usr/doc/sed-$VERSION 43 cp -a \ 44 ANNOUNCE AUTHORS BUGS COPYING* INSTALL NEWS README README.boot THANKS TODO \ 45 $PKG/usr/doc/sed-$VERSION 46 gzip -9 $PKG/usr/man/man?/*.? 47 rm -f $PKG/usr/info/dir 48 gzip -9 $PKG/usr/info/* - Une fois l'installation temporaire effectuée, on crée un répertoire ''/bin'' dans le dossier temporaire (l. 34). Puis on déplace l'exécutable ''sed'' dans ce dossier((Cette manoeuvre est destinée à mettre l'exécutable de sed dans le bon dossier car tout exécutable requis par le système lors de son initialisation et non spécifique au superutilisateur doit se trouver dans ''/bin''.)) (l. 35). Ensuite, dans un //sous-shell//, on entre dans le dossier en question puis on crée avec la commande ''ln'' un lien symbolique de l'exécutable ''sed'' vers celui-ci (l. 35). La nature du lien est ici déterminée grâce à l'argument ''-s'' passé à ''ln'', ''-f'' commandant pour sa part l'écrasement d'un éventuel lien préexistant. Lier de la sorte évitera d'éventuels désagréments conséquents au changement de répertoire. Enfin, ligne 37, on affecte via ''chown'' le propriétaire ''root'' et le groupe ''bin'' aux deux dossiers et à leur contenu((Ce changement de groupe est maintenant abandonné : tout doit désormais être attribué au groupe root.)) (''-R'' indique ici encore la récursivité) ; - Dans un //sous-shell// (l. 38-41), on entre dans le dossier temporaire puis on procède au //stripping// : l'affinement des exécutables et des bibliothèques dynamiques. On pratique cette opération car la compilation introduit dans les objets qu'elle génère des informations nécessaires à sa propre conduite et au débogage mais ne jouant aucun rôle dans l'usage des binaires. Ces informations pouvant doubler voir tripler la taille d'un binaire, une petite toilette s'impose donc, ce qui est la précisément mission du //stripping//. La commande utilisée ici use de nombreux tuyaux ((« //pipe// » en anglais.)), il convient donc d'en distinguer chaque membre pour mieux comprendre le fonctionnement de l'ensemble. Nous nous référons à la première instance (l. 39), la seconde fonctionnant de la même manière mais avec pour objet les bibliothèques dynamiques au lieu des exécutables. * ''find .'' va lister récursivement tous les fichiers présents dans le répertoire. Il a l'avantage de restituer cette liste ligne par ligne en donnant le chemin de chaque dossier ou fichier. Cela le rend très pratique lorsqu'il est connecté à un tuyau ; * ''xargs file'' est un composé de deux commandes : ''xargs'' qui sert à exécuter des commandes à partir de l'entrée standard et ''file'' qui retourne des informations sur la nature des fichiers. Ici ''xargs'' exécute ''file'' sur tous les fichiers envoyés par ''find'' ; * ''grep'' sert à extraire des chaînes de caractères à partir d'un fichier ou de l'entrée standard. Ici on lui ordonne d'extraire tous les résultats de ''file'' qui contiennent //executable// puis de ne retenir parmi ceux-ci que ceux qui contiennent //ELF//((« //Executable and Linking Format// »)). Cela a pour but de trier les fichiers concernés par le //stripping//, car par exemple affiner un fichier en texte brut ne rime à rien ; * Si vous vous aventurez à tester ''file'' sur un exécutable (ex. ''file /bin/bash''), vous vous apercevrez qu'il y a beaucoup d'informations. Or la seule qui nous intéresse, à présent que le tri est fait, c'est le chemin des fichiers retenus. C'est là qu'intervient ''cut'' qui comme son nom l'indique sert à opérer des coupes. L'argument ''-f 1'' lui ordonne de couper le premier champs de l'entrée standard, avec pour délimiteur de champs le caractère ":" indiqué par l'argument ''-d''. Appliqué au résutat d'une commande ''file'' cela retourne juste ce que nous voulons : le chemin absolu des fichiers ; * Arrivés à la dernière extrêmité de notre commande, nous avons donc une série de fichiers affinables, ne reste plus qu'à les affiner effectivement. Pour ce, on ordonne à ''xargs'' d'appliquer sur eux la commande ''strip''. L'argument ''--strip-unneeded'' évite un nettoyage trop abrasif qui détruirait des choses utiles : seul le superflu est enlevé. On remarquera au passage que les messages d'erreur et les avertissements qui auraient pu intervenir dans cette longue chaîne de commande sont tous envoyés vers ''/dev/null'' (l'équivalent de « nulle-part » pour le système). - Après l'affinement, on procède à la création du répertoire où l'on va stocker les « docs » (l. 42). Celles-ci correspondent aux fichiers informatifs contenu dans l'archive des sources (''README'', ''INSTALL'', ''NEWS'', licences, etc. ). Tous les fichiers ainsi copiés (l. 43-45) étant propres au logiciel compilé, chaque ''Slackbuild'' a par conséquent une liste différente. Bien sûr il existe en la matière des noms de fichier standards (''README'' et ''INSTALL'' en sont), mais il y a toujours un certain flou dans ce qu'il convient d'intégrer ou non aux docs ; - Lignes 46 à 49 intervient le traitement des //man-pages// et des //info-pages//. Celles-ci correspondent à deux formats de documentation. Le premier est lu via la commande ''man'', le second via la commande ''info''. L'usage veut que toutes les //man-pages// soient compressées (l. 46) par ''gzip'' avec un taux de compression maximum (''-9'' en argument). On procède de même avec les //info-pages// (l. 48), à cette petite nuance que pour elles on prend soin de supprimer le fichier ''dir'' (l. 47). Celui-ci correspond à l'index général des //info-pages//, il est présent dans le paquet ''texinfo'' (répertoire ''ap/'') et ne doit par conséquent pas être réécrit. Là encore les informations traitées ne le sont pas de manière générique mais de manière propre au logiciel empaqueté. Si par exemple ''sed'' avait eu une //man-page// française, celle-ci n'aurait pas été compressée (elle aurait été dans ''$PKG/usr/man/fr/man?/''). ==== Le fichier slack-desc ==== 49 mkdir -p $PKG/install 50 cat $CWD/slack-desc > $PKG/install/slack-desc Ligne 49 est créé un répertoire ''install/''. Celui-ci est un peu spécial en ce qu'il ne sera pas intégré dans le système de fichiers une fois le paquet installé. En fait il contient des informations sur le paquet et, le cas échéant, des scripts d'installation (cf. [[#Appendice A : Utiliser des scripts de d'installation|Appendice A , Utiliser des scripts de d'installation]]). Les informations sur le paquet sont contenues dans un fichier ''slack-desc''. C'est lui que la commande ''cat'' édite puis redirige dans ''install/'' (l. 50). Avec les ''Slackbuild'' de Patrick, il est toujours mis à part dans le répertoire d'exécution du script. Un ''slack-desc'' obéissant à des règles de rédaction précises, il convient de se pencher un peu sur ce fichier. Voici reproduit le contenu du ''slack-desc'' de ''sed'' : # HOW TO EDIT THIS FILE: # The "handy ruler" below makes it easier to edit a package description. Line # up the first '|' above the ':' following the base package name, and the '|' # on the right side marks the last column you can put a character in. You must # make exactly 11 lines for the formatting to be correct. It's also # customary to leave one space after the ':'. |-----handy-ruler------------------------------------------------------| sed: sed (stream editor) sed: sed: This is the GNU version of sed, a stream editor. A stream editor is sed: used to perform basic text transformations on an input stream (a file sed: or input from a pipeline). It is sed's ability to filter text in a sed: pipeline which distinguishes it from other types of editors. sed: sed: sed is a required package (it is needed by many system scripts). sed: sed: sed: Comme on peut le voir, un ''slack-desc'' orthodoxe suit cinq règles : - il doit faire 11 lignes ni plus ni moins, chacune débutant par le nom du logiciel décrit ; - de la fin du nom du logiciel jusqu'à la fin d'une ligne, il y a 70 caractères maximum (ponctuations et blancs inclus), le ''handy-ruler'' montre d'ailleurs bien la limite ; - le nom du logiciel débutant une ligne est toujours suivi de « : » puis d'un espace ; - la première ligne contient le nom du logiciel suivi entre parenthèses d'une brève définition de celui-ci ; - le corps du ''slack-desc'' contient une description plus précise de ce qui caractérise le logiciel. ==== Empaquetage final ==== 52 cd $PKG 53 makepkg -l y -c n ../sed-$VERSION-$ARCH-$BUILD.tgz Le ''slack-desc'' en place, on va à la racine du répertoire d'installation temporaire (l. 51) pour procéder à l'empaquetage. Les arguments passés à ''makepkg'' servent à répondre aux questions posées sans entrer dans le mode interactif (cf. [[#L'empaqueteur Slackware : makepkg|L'empaqueteur Slackware , makepkg]]). Les liens symboliques seront donc conservés (''-l y'') et les permissions ne seront pas initialisées (''-c n''). Cette dernière opération est en effet inutile puisque le ''Slackbuild'' s'en est déjà chargé, et de manière beaucoup plus fine. Le paquet sera créé dans le répertoire parent de celui de l'installation temporaire (en l'occurence ''/tmp'') et il prendra la forme de ''---.tgz'' (dans le cas qui nous occupe : ''sed-4.0.9-i486-2.tgz''). Il est important pour un paquet de respecter cette structure de dénomination, autrement le ''slack-desc'' ne sera pas affiché lors de l'installation, et cela risque de générer des ambiguïtés lors des mises à jour. ==== Que retenir ? ==== Après cette analyse d'un ''Slackbuild'' de Patrick Volkerding, il est possible de définir un cahier des charges auquel nos propres scripts de compilation devront se plier : * Les exécutables doivent être installés dans le bon dossier selon leur importance pour le système. * La propriété du contenu du paquet doit être accordée au superutilisateur et à son groupe((Par défaut du moins, car il peut y avoir des exceptions pour certains composants.)). * Les exécutables et bibliothèques dynamiques doivent être affinés((Il peut cependant arriver dans de rares cas que l'affinement des bibliothèques dynamiques pose problème. Explorez cette piste si vous constatez une instabilité du programme à l'usage.)). * Les « docs » doivent être récupérées et stockées dans ''/usr/doc/-''((Ou ''/usr/local/doc/-'' si vous optez le préfixe ''usr/local''.)). * Les //man-pages// doivent être compressées par ''gzip'' avec un taux de compression maximum. De même pour les //info-pages// pour lesquelles il faut en plus prendre soin de supprimer l'index. * Le ''slack-desc'' doit être rédigé comme il se doit et copié dans ''install/''. * Le nom du paquet doit respecter la forme ''---.tgz''. Comme on peut le constater, les points observer pour faire un paquet « orthodoxe » sont au final peu nombreux. C'est que la politique Slackware veut que les logiciels distribués soit le plus proches possible de ceux livrés par les développeurs. Il n'y a donc rien de sorcier à empaqueter un logiciel en suivant celle-ci et, le temps d'intégrer ces règles et quelques rudiments de //shell//, on arrive assez vite à produire des paquets très corrects. ===== Conclusion ===== Raffinant à peine les procédures de construction et d'installation de logiciels habituelles, la Slackware propose des outils et une méthode plutôt basiques mais efficaces pour intégrer proprement de nouveaux logiciels au système. En effet, en passant par de simples scripts //shell// cette merveilleuse distribution laisse à chacun la possibilité de comprendre et de s'approprier les tenants et aboutissants de sa procédure d'empaquetage, sans jamais rien imposer au demeurant. C'est du moins ce que ce manuel a tenté de montrer, tout d'abord en exposant les bases « standards » de la compilation sous GNU/Linux, puis en analysant un ''SlackBuild'' de Patrick Volkerding //himself//. En espérant y être parvenu ou ne serait-ce qu'y avoir significativement contribué, je vous souhaite de passer à votre tour de joyeuses heures à trousser et peaufiner vos propres scripts. En un mot comme en mille et pour reprendre celui de notre mainteneur préféré : //enjoy !//. ^_^ ===== Appendice A : utiliser des scripts de d'installation ==== Le ''Slackbuild'' de Patrick Volkerding ne nous a pas donné matière à aborder le problème des scripts d'installation, problème qu'il est pourtant souhaitable d'aborder si on veut être un peu complet sur l'empaquetage Slackware. Aussi nous ajoutons ici un cours appendice à cet effet. Le but d'un script d'installation est tout simplement d'exécuter certaines commandes une fois le paquet installé, en général pour parfaire son intégration au système. Leur mise en oeuvre dans un script d'empaquetage est identique à celle du ''slack-desc'', exception faite de la cible. Pour définir celle-ci, il faut tout d'abord savoir quel type de script vous voulez utiliser car il en existe en effet plusieurs. Plutôt que de nous lancer dans de longues explications, nous proposons ici une traduction commentée de la section « //INSTALLATION SCRIPTS// » rédigée par Patrick Volkerding dans la //man-page// de ''makepkg'' : > Il y a 3 types de scripts d'installation supportés par le système de paquet Slackware. > > Le premier type regroupe les scripts d'installation primaires. Ils se trouvent dans ''./install'' et doivent se nommer ''doinst.sh'' pour être reconnus. Il doivent également (eux et les autres scripts d'installation) être écrits conformément à la syntaxe du //Bourne shell// de base telle que reconnue par le Ash shell, car c'est ce shell qui sera utilisé pour exécuter ces scripts si vous faites une installation à partir d'une disquette d'installation Slackware. C'est un piège courant, prenez garde à ne pas utiliser la syntaxe ''bash'', car les scripts fonctionneront bien s'ils sont installés à partir du disque dur mais planteront s'ils sont installés à partir d'une disquette. Lorsque le paquet est destiné à un usage personnel, cela n'est pas un problème. Attention, cependant, si vous comptez partager votre paquet avec d'autres utilisateurs. Les script d'installation primaires sont exécutés immédiatement après l'installation du paquet par ''installpkg'', ''pkgtool'', ou ''setup''. Si jamais vous êtes amené à inclure un script d'installation dans vos paquets, c'est probablement ce type de scripts que vous utiliserez. Il doit être stocké((Nous disons « stocké », car le fichier ''doinst.sh'' contient également les commandes permettant la restitution des liens symboliques lorsque leur conservation est ordonnée (cf. [[#L'empaqueteur Slackware : makepkg|L'empaqueteur Slackware , makepkg]]). Normalement ces commandes seront ajoutées à la suite des vôtres. Si toutefois ces dernières requièrent que les liens symboliques soient réstitués avant leur exécution, vous pouvez demander à makepkg de mettre les premières au début du script en lui passant l'argument ''-p'' lors de la génération du paquet. Pour plus d'informations consultez la //man-page// de ''makepkg''.)) dans ''install/doinst.sh'' et est exécuté immédiatement après l'installation du paquet . Voici un exemple basique de ce que pourrait être un tel script intégré((Ce script étant stocké, il ne contient pas la traditionnelle première ligne ''#!/bin/sh''.)) dans notre script d'empaquetage : cat >${TMP_DIR}/install/doinst.sh< Ici, il servirait à mettre automatiquement à jour la base de données de ''shared-mime-info'' employée par certains logiciels pour partager leurs fichiers ''MIME''((//Multipurpose Internet Mail Extensions//. Les fichiers ''MIME'' servent à typer les documents selon leurs extensions, ce qui permet notamment aux environnements de leur associer des applications.)). Le //shell// ''ash''((Alquimst SHell)) dont il est question a pour vocation de rester le plus proche possible du //Bourne shell//, le //shell// UNIX historique. Le //shell// ''bash'' étant un //Bourne shell// revu et augmenté , il se peut que sa syntaxe pose problème à ''ash''. Il est par conséquent conseillé d'installer ce dernier pour tester les scripts((Dans ce cas, c'est la commande ''ash'' qui doit exécuter le script : ''ash script.sh''. Le paquet est disponible dans le répertoire ''ap/''q de la Slackware. Le paquet ''ash'' faisant moins de 150K une fois décompressé, l'installer ne coûte vraiment pas grand chose.)). > Le second regroupe les scripts de configuration. Ils se situent dans le sous-répertoire ''./var/log/setup'' et doivent porter un nom commençant par « setup » pour être reconnus. Un exemple en est le script de fuseau horaire : ''/var/log/setup/setup.timeconfig''. Ces scripts sont exécutés pendant la phase ''CONFIGURE'' du setup et sont ré-exécutés à chaque fois que l'utilisateur lance l'option ''CONFIGURE'' à partir de ''setup'' lorsqu'arrivera la dite phase. En règle générale, l'utilisateur passera au travers de cette phase du setup, poursuivant l'installation de tous les paquets. Tout ce qui a besoin d'être interactif devrait être contenu dans un de ces scripts afin d'éviter de suspendre la procédure d'installation du paquet au cours du ''setup''. Il est peu vraisemblable que vous ayez jamais à manipuler de tels scripts. En effet, ils ne servent que durant la phase ''SETUP'' de l'installation Slackware ou via l'option du même nom proposée par la commande ''pkgtool''((La //man-page// ici traduite date un peu. La commande ''setup'' à laquelle ce passage fait référence a été retirée de la Slackware dans sa version 8.1. Celle-là était alors à la fois un outil d'installation et de maintenance. Lorsqu'elle a été retirée, la commande ''pkgtool'' a récupéré certaines de ses fonctionnalités, notamment sa capacité à exécuter les scripts de configuration.)). Autant dire qu'ils ne sont utiles que pour des paquets susceptibles d'être appelés durant l'installation initiale. Ils servent généralement pour la détection du matériel et la configuration de certains services : ''netconfig'' ou ''xwmconfig'' en sont de bons exemples. Comme ils ne sont pas automatiquement exécutés lors de l'installation du paquet, vous pouvez toujours, si vraiment vous devez les utiliser, faire un script d'installation primaire prévenant l'utilisateur de la nécessité de les lancer et appelant ''pkgtool'' : cat >${TMP_DIR}/install/doinst.sh< Les messages seront affichés après l'installation du paquet, puis la commande ''sleep'' marquera une pause de cinq secondes avant le lancement de ''pkgtool''. Gardez cependant à l'esprit que, comme indiqué, ces scripts ne devraient être mis en oeuvre que pour ce qui nécessite l'entrée l'informations de la part de l'utilisateur. Dans tous les autres cas, préférez donc les scripts d'installation primaires. > Le troisième regroupe les scripts onlyonce ((En français, « rien qu'une fois »)). Comme l'indique leur nom et à la différence des scripts de configuration standards, ils sont exécutés seulement une fois après l'installation du paquet. Ces scripts se situent également dans le sous-répertoire ''./var/log/setup'' et leurs noms, en plus commencer par « setup », doivent également contenir la chaîne « onlyonce ». À titre d'exemple, on pourrait imaginer un script portant le nom ''/var/log/setup/setup.onlyonce.testscript''. Cette famille de scripts se comporte en fait exactement comme celle des scripts d'installation secondaires. La distinction dont il est question ici n'avait en effet de sens qu'avec l'ancienne commande ''setup''((L'option ''CONFIGURE'' de ''setup'' avait pour effet de lancer la totalité des scripts de configuration. Les scripts ''onlyonce'' permettaient donc de créer des exceptions. À présent que ''pkgtool'' propose de choisir les scripts à exécuter, cela n'a plus lieu d'être)). ===== Appendice B : licence du SlackBuild de Patrick Volkerding ===== Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999 Patrick Volkerding, Moorhead, Minnesota, USA. Copyright 2001, 2002, 2003, 2004 Slackware Linux, Inc. Concord, CA, USA. All rights reserved. Redistribution and use of this software, with or without modification, is permitted provided that the following conditions are met: - Redistributions of this software must retain the above copyright notice, this list of conditions and the following disclaimer. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.