Créer et exécuter des recettes

On se base sur la recette générique de 0Linux pour créer rapidement des paquets. La recette a été simplifiée et comprend des fonctions pour automatiser les tâches rébarbatives. Elle inclut toutes les commandes que l'on appellerait habituellement sur la ligne de commande, en s'aidant des fonctions pré-enregistrées dans /usr/share/0outils/fonctions_paquets.sh .

La recette équivaut en fait à empaqueter un logiciel manuellement sur le terminal, ou via un petit script, en le compilant et en l'installant à un emplacement spécifique puis à le passer à spackpkg pour en faire un paquet pour 0Linux, installable avec spackadd.

Recette exemple

Voici une recette typique (ici a/xz/xz.recette) afin de vous donner une idée générale :

#!/usr/bin/env bash
. /usr/share/0outils/fonctions_paquets.sh
 
NAMESRC=xz
VERSION=5.0.5
EXT=tar.gz
NAMETGZ=xz
WGET=http://tukaani.org/$NAMESRC/$NAMESRC-$VERSION.$EXT
DESC="Outil de compression basé sur l'algorithme LZMA"
 
telecharger_sources
preparer_sources # À partir d'ici, on se trouve dans les sources décompactées.
cflags
 
# Compilation :
CFLAGS="${FLAGS}" CXXFLAGS="${FLAGS}" \
./configure \
	--prefix=/usr \
	--sysconfdir=/etc \
	--localstatedir=/var \
	--libdir=/usr/lib${LIBDIRSUFFIX} \
	--mandir=/usr/man \
	--infodir=/usr/info \
	--docdir=/usr/doc/${NAMETGZ}-${VERSION} \
	--build=${PKGARCH}-0linux-linux-gnu
 
make -j${JOBS} || make
fakeroot make install DESTDIR=${PKG}
 
installer_doc
 
# On complète la documentation :
cp -a doc/* ${PKG}/usr/doc/${NAMETGZ}-${VERSION}
 
creer_post_installation
stripper
empaqueter
 
# C'est fini.

Exécuter une recette

Les recettes sont exécutables (et censées l'être) :

chmod +x unlogiciel.recette

On empaquète un logiciel en exécutant simplement la recette :

./unlogiciel.recette

On peut ajouter les messages concernant l'exécution de bash pour avoir des messages plus précis sur chaque action de l'interpréteur :

bash -ex unlogiciel.recette

Une variable a été prévue pour les utilisateurs ne voulant pas avoir toutes les archives des sources directement dans le dépôt des recettes, mais plutôt rangées à part, dans leur propre répertoire : c'est la variable $PKGSOURCES. Si l'on dispose déjà des archives quelque part, on appellera alors :

PKGSOURCES=/quelque/part/archives_sources ./unlogiciel.recette

On peut aussi plutôt affecter une variable d'environnement de façon temporaire dans le shell courant :

export PKGSOURCES=/quelque/part/archives_sources

Ou bien de façon permanente :

echo "export PKGSOURCES=/quelque/part/archives_sources" >> ~/.bashrc

Les variables d'environnement

Le script fonctions_paquets.sh, chargé en début de recette, définit des variables d'environnement comme suit (extrait du fichier) :

# Emplacement où on compile et on empaquète :
MARMITE=${MARMITE:-/tmp/0-marmite}
 
# ...et où on stocke les journaux de compilation :
MARMITELOGS=${MARMITELOGS:-${MARMITE}/logs}
 
# Emplacement où on stocke les archives sources :
PKGSOURCES=${PKGSOURCES:-${CWD}}
 
# Emplacement du dépôt des paquets résultant de la construction :
PKGREPO=${PKGREPO:-/usr/local/paquets}

On peut définir ces variables critiques pour la construction des paquets en les définissant via export ou via un script dans ~/.bashrc, ou encore via la ligne de commande.

Les voici dans un fichier exemple que vous pouvez créer et exécuter via source ou bien ajouter à votre fichier ~/.bashrc. Si vous ne désirez pas personnaliser ces variables, vous n'avez rien à faire, elles ont chacune une valeur par défaut :

export PKGSOURCES=/home/appzer0/0/pub/archives_sources   # Vaut "répertoire courant par défaut", donc aux côtés de la recette, non recommandé (pollue le dépôt des recettes avec des archives sources en vrac)
export MARMITE=/tmp/0-marmite                            # Vaut '/tmp/0-marmite' par défaut
export PKGREPO=/home/appzer0/0linux/theta                # Vaut '/usr/local/paquets' par défaut'

Comme on le voit ici, je définis PKGREPO à un répertoire theta, qui est la version du système 0Linux que j'exécute à ce moment-là. Les paquets créés se rangeront alors dans un répertoire /home/appzer0/0linux/theta/ARCHITECTURE, nommé i686, x86_64 ou arm selon l'architecture utilisée. Je recommande d'en faire autant.

PKGSOURCES est le répertoire contenant les archives sources téléchargées par chaque recette. Par défaut, les archives se téléchargent dans le même répertoire que la recette, rendant ainsi vite le dépôt surchargé d'archives. À éviter, à mon humble avis… Utilisez un dépôt séparé pour les archives sources et affectez ce répertoire à PKGSOURCES.

:!: Le script fonctions_paquets.sh se charge aussi de déplacer chaque archive source dans un répertoire dédié si celles-ci sont encore rangées en vrac. Ainsi, dans notre cas, les sources du paquet libpng seront rangées (ou déplacées) dans /home/appzer0/0/pub/archives_sources/libpng/libpng-1.2.3.tar.gz.

$MARMITE contient la sous-hiérarchie pour déballer les sources téléchargées et les compiler ($TMP) et stocker les fichiers finaux avant de les empaqueter ($PKG). $TMP est un sous-répertoire nom_du_paquet/sources et $PKG est un répertoire d'accueil des fichiers avant empaquetage nom_du_paquet/paquet. Utiliser la variable $MARMITE par défaut, /tmp/0-marmite, conviendra à la plupart. Schématiquement, ça donne :

/tmp/0-marmite/
└── libtruc
    ├── paquet
        └── usr... (toute la hiérarchie du futur paquet)
    └── sources
        └── libtruc-1.2.3
            └── src... (les sources originales de 'libtruc')

Les variables dans les recettes

On définit d'abord les variables pour le nom des sources du paquet, la version, l'extension de l'archive, le nom du paquet (qui peut être différent du nom des sources) :

NAMESRC=LibTruc  # nom des sources, par exemple : Python
VERSION=0.1.2.3  # version, par exemple : 2.6
EXT=tar.xx       # extension de l'archive des sources : tar.bz2, zip, bin, tgz, etc.
NAMETGZ=libtruc  # nom du paquet résultant : python (sans majuscules)
  • $NAMETGZ peut contenir des tirets, de la ponctuation, des chiffres… Elle NE doit PAS contenir d'espaces, de majuscules, de caractères accentués ou autre symboles exotiques. Il faut s'en tenir à l'alphabet [a-z] et aux chiffres [0-9] ainsi qu'aux caractères de ponctuation usuels : - _ : +

On peut ignorer les définitions des variables $NAMESRC, $NAMETGZ et $EXT ; elles sont d'ailleurs de plus en plus délaissées :

  • $NAMETGZ, si elle n'est pas définie, prendra le nom de la recette. Exemple : la recette libtruc.recette affectera automatiquement la variable NAMETGZ=libtruc.
  • $NAMESRC, si elle n'est pas définie, prendra la valeur de $NAMETGZ tout simplement.
  • $EXT représente l'extension de l'archive source mais n'a pas vraiment d'utilité, vous pouvez directement indiquer cette extension dans l'URL de téléchargement des sources.

Le script fonctions_paquets.sh crée des variables d'office :

  • Les sources décompactées se trouvent dans $TMP, valant /tmp/0-marmite/NOMDUPAQUET/sources/ par défaut
  • L'arborescence finale du futur paquet est rangée dans $PKG, valant /tmp/0-marmite/NOMDUPAQUET/paquet/ par défaut
  • Le paquet lui-même sera rangé dans $OUT, valant par défaut /usr/local/paquets/ARCHITECTURE/catégorie/NOMDUPAQUET/.

Pour définir un emplacement pour le dépôt de paquets autre que /usr/local/paquets, il convient d'affecter la variable $PKGREPO. Par exemple votre serviteur utilise PKGREPO=/home/appzer0/0/pub/paquets/theta pour construire 0Linux theta.

On spécifie ensuite l'emplacement des sources sur le Net dans la variable WGET. Cette variable peut être renseignée de 2 manières :

Comme une variable simple (mais toujours modifiable depuis la ligne de commande) :

WGET=http://ftp.gnu.org/gnu/$NAMESRC/$NAMESRC-$VERSION.$EXT

Ou bien comme un tableau, contenant de multiples archives, certains paquets ayant besoin de plusieurs archives (par exemple pour leur documentation, des exemples, des démonstrations, des bibliothèques supplémentaires, etc.) :

WGET=(http://ftp.gnu.org/gnu/$NAMESRC/$NAMESRC-$VERSION.$EXT
      http://ftp.gnu.org/gnu/$NAMESRC/$NAMESRC-docs-$VERSION.$EXT
      http://ftp.gnu.org/gnu/$NAMESRC/$NAMESRC-html-$VERSION.$EXT
     )

Cette variable sera traitée par la fonction telecharger_sources (voir plus bas). Voyez pour exemple la recette d/git/git.recette, qui contient un tableau.

Puis vient la description du paquet dans DESC :

DESC="Des bibliothèques et outils pour faire fonctionner quelque chose de précis..."

spackdesc s'occupera de formater cette description pour qu'elle tienne sur 79 caractères maximum, sur plusieurs lignes si besoin est. La longueur est libre mais elle doit néanmoins rester raisonnablement brève car elle est affichée à l'installation par spackadd.


Les fonctions de 0Linux

Les fonctions de 0Linux utilisées dans les recettes sont appelées via cette ligne qu'on retrouve dans chaque recette :

. /usr/share/0outils/fonctions_paquets.sh

Ce script rend disponible les fonctions suivantes :

telecharger_sources
preparer_sources
cflags
installer_doc
creer_post_installation
stripper
empaqueter

On peut la plupart du temps les laisser, elles ne causent pas d'erreurs, sauf cas particulier.

Ce script s'occupe également de quelques tâches préliminaires :

  • Il nettoie tout ancien paquet éventuellement encore présent
  • Il crée automatiquement un journal du déroulement de la compilation et de l'empaquetage (« log » en anglais) sous /$MARMITE/logs, $MARMITE se trouvant par défaut dans /tmp/0-marmite ; on a ainsi les messages à l'écran et un journal qui se génère à part simultanément pour consultation ultérieure. Le « log » est ensuite compressé avec xz dans la fonction empaqueter et placé dans la documentation du paquet, sous /usr/doc/PAQUET-VERSION/PAQUET-VERSION.log.xz : on pourra le consulter à loisir avec par exemple xzless ou xzcat.
  • Il s'occupe aussi d'ajouter au fichier *.dep décrivant les dépendances tous les paquets supplémentaires détectés comme nécessaires. Lisez le script fonctions_paquets.sh, il est bien commenté et fait de nombreuses choses.

telecharger_sources

telecharger_sources télécharge la ou les archives des sources à(aux) (l')adresse(s) définie(s) dans $WGET, si la ou les archives sont absentes, que celle-ci soit une simple URL ou bien un tableau de plusieurs URL (voir plus haut dans cette page) puis s'occupe de vérifier l'intégrité des archives téléchargées.

Depuis 0outils 12.9, telecharger_sources gère également les dépôts git. Il suffit de renseigner l'adresse du dépôt commençant par « git: ». Le commit concerné doit se retrouver dans la variable VERSION. On spécifie les 10 premiers caractères du « hash » du commit voulu. Exemple :

VERSION=13eb208681 # Les 10 premiers caractères du commit désiré
WGET=git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git

Pour éviter de cloner le dépôt à chaque fois, telecharger_sources va se charger de faire plusieurs choses :

  • cloner le dépôt git via git clone
  • faire un git checkout sur le commit spécifié dans VERSION
  • nettoyer tout répertoire .git
  • renommer le répertoire principal en PAQUET-VERSION
  • créer une archive compressée nommée PAQUET-VERSION.tar.xz du répertoire PAQUET-VERSION
  • la ranger dans PKGSOURCES/PAQUET

preparer_sources

preparer_sources nettoie tout répertoire $PKG, $TMP/<sources> ou $TMP/<sources>-build éventuellement présent, vérifie l'intégrité de l'archive source téléchargée par telechager_sources, détecte son répertoire principal s'il existe , décompacte l'archive puis se place à l'intérieur, dans $TMP/<répertoire_des_sources>. Ce répertoire est affecté à la variable $TMP/$NAME. Elle redéfinit également les permissions des sources afin qu'elles soient « saines » (c'est-à-dire qu'elles respectent un « umask » de 022).

Si l'archive source contient plusieurs répertoires ou des fichiers en vrac, elle est considérée comme « sale » et son contenu est donc extrait dans un répertoire spécial qui porte tout simplement le nom de l'archive, à savoir $TMP/nomdelarchive.tar.gz/. Ce répertoire est également affecté à $TMP/$NAME.

Ainsi le fait d'appeler preparer_sources fera en sorte que le répertoire final dans lequel on va se placer sera, selon les archives sources libpropre-1.2.3.tar.gz et libcrado-1.2.3.tar.gz :

cd $TMP/libpropre-1.2.3/ # libpropre a un répertoire principal, c'est propre.
cd $TMP/libcrado-1.2.3.tar.gz/ # libcrado a un contenu bordélique ! On crée un répertoire spécial et on extrait tout dedans.

Cette fonction ne gère pas encore les archives spéciales, comme les *.run, les *.7z ou les .rar. Ce comportement est à corriger.

Si $WGET contient plusieurs archives, preparer_sources recherchera l'archive nommée $NAMESRC-$VERSION.$EXT. Si elle n'existe pas, il faudra simplement la spécifier :

preparer_sources $NAMESRC-$VERSION_Linux.source.$EXT

Le fait de pouvoir spécifier une archive précise permet également d'écrire des recettes multiversion (par exemple, libpng contient plusieurs versions des sources et chacune doit être compilée. On appellera donc preparer_sources sur chaque version désirée pour se placer dans le répertoire source de chacune d'entre elles).


cflags

cflags détecte l'architecture visée en testant la sortie de la commande uname -m de la machine hôte et la place dans la variable $PKGARCH ; il faut l'utiliser à chaque fois, même si aucune compilation n'est effectuée car c'est elle qui décide de la machine cible ainsi que du suffixe des répertoires des bibliothèques (lib, lib64, etc.).

Elle positionne le suffixe du répertoire général des bibliothèques dans la variable $LIBDIRSUFFIX. On spécifiera donc partout dans la recette lib${LIBDIRSUFFIX}) :

  • pour i686 : LIBDIRSUFFIX=“” (afin de placer dans lib)
  • pour x86_64 : LIBDIRSUFFIX=“64” (afin de placer dans lib64)
  • pour tout le reste : LIBDIRSUFFIX=“”

Elle positionne les drapeaux d'optimisation et autres CFLAGS dans la variable $FLAGS :

  • pour i686 : FLAGS=“-m32 -O2 -march=i686 -pipe”
  • pour x86_64 : FLAGS=“-O2 -fPIC -pipe”
  • pour ARM : FLAGS=“-O2 -march=armv7-a -mfpu=vfpv3-d16 -pipe”
  • pour tout le reste : FLAGS=“-O2 -pipe”

Elle positionne les appels au compilateur :

  • pour i686 : CC=“gcc -m32” et CXX=“g++ -m32”
  • pour x86_64 : CC=“gcc” et CXX=“g++”
  • pour tout le reste : CC=“gcc” et CXX=“g++”

Elle positionne l'appel à l'éditeur de liens ld :

  • pour toutes les architectures : LDFLAGS=“-L/usr/lib${LIBDIRSUFFIX}” -Wl,-O1,–as-needed,–sort-common

Elle positionne l'emplacement de pkg-config :

  • pour toutes les architectures : PKG_CONFIG_PATH=“/usr/lib${LIBDIRSUFFIX}/pkgconfig”

Tous ces drapeaux sont personnalisables au sein de plusieurs fichiers, notamment /etc/0outils/drapeaux-ARCHITECTURE.conf et /etc/0outils/drapeaux.conf, qui reprennent les drapeaux vus plus haut mais qui permettent de les modifier. Privilégiez toujours la personnalisation du fichier drapeaux-ARCHITECTURE.conf car il n'est jamais écrasé lors d'une mise à niveau du paquet 0outils. Seul drapeaux.conf est écrasé.

On peut également créer/copier ces fichiers dans le répertoire ~/.0outils et ainsi pouvoir définir ces drapeaux en tant que simple utilisateur (les recettes n'utilisant pas root pour construire). Ces fichiers sous $HOME auront alors la priorité sur le reste.

La fonction cflags() définit également les capacités de parallélisation de la machine en prenant en compte le nombre de processeurs ou de cœurs ainsi que la disponibilité de l'Hyper Threading, ce afin d'accélérer la compilation :

  • pour les processeurs Intel gérant l'Hyper Threading : JOBS=(<nombre_de_processeurs>*2)+1
  • pour le reste : JOBS=<nombre_de_processeurs>+1

On peut forcer une autre architecture que celle de l'hôte pour certains cas spéciaux (compilation croisée pour la prise en charge du multilib notamment, etc.) en appelant la fonction avec un paramètre. Par exemple :

cflags i686

… forcera la compilation en i686 même si l'hôte est un x86_64. Cette fonction est souvent utilisée dans les recettes nécessitant de gérer le mécanisme « multilib », comme c'est le cas pour les recettes x86_64 nécessitant des bibliothèques 32 bits i686 au sein du même paquet. Voyez la recette zlib.recette pour un exemple concret de recette multilib.

On peut également forcer une architecture non native (si on veut compiler uniquement du 32 bits i686 sur une 0Linux 64 bits) en spécifiant sur la ligne de commande la variable $FORCE_PKGARCH. Cette variable ne sert que dans de rares cas, par exemple générer des paquets purs i686 sur un hôte 64 bits prenant en charge le multilib i686.


configure_make_makeinstall

:!: Disponible uniquement à partir de 0outils 12.8

Cette fonction représente un raccourci qui peut servir pour les cas (trop rares) où la procédure de construction est parfaitement standard (commandes ./configure ; make ; make install). Elle déduit les options disponibles dans le configure ( –prefix, –localstatedir, –libdir, –mandir, etc.) et tente de les spécifier au mieux pour 0Linux.

Elle déduit également le mot-clé du répertoire final d'installation (DESTDIR, install_prefix, INSTALL_ROOT) pour l'étape du make install. Inutile de préciser que ce genre de fonction peut être pratique mais qu'elle ne peut satisfaire tous les cas d'utilisation. À utiliser avec précaution. Vérifiez bien le contenu du paquet final !


installer_doc

La documentation de chaque paquet est détectée et rangée dans /usr/doc/paquet-version. La fonction installer_doc intègre d'office un maximum de noms de fichiers de doc génériques et s'occupe de les copier :

installer_doc()
cp -a AUTHORS BUGS ?hange?og* *CHANGES* CODING* Contents *COPYING* COPYRIGHT* Copyright* \
	compile EXPAT *FAQ* HACKING *INSTALL* KNOWNBUGS *LEGAL* *LICEN?E* MAINTAIN* *NEWS* \
	*README* THANK* TODO TRANSLATORS *license* *readme* ${PKG}/usr/doc/${NAMETGZ}-${VERSION} 2>/dev/null || true

On s'occupera d'ajouter manuellement, à la suite de l'appel à cette fonction, la doc supplémentaire qui peut manquer, qu'on copiera donc dans ${PKG}/usr/doc/${NAMETGZ}-${VERSION}.

Si l'on nécessite de placer de la doc dans des répertoire précis, par exemple dans le cas des recette multiversion, on spécifiera un répertoire :

installer_doc ${NAMETGZ}-${VERSION}/libvieilleversion-0.1.0

…afin d'installer la doc détectée automatiquement dans un sous-répertoire ${PKG}/usr/doc/${NAMETGZ}-${VERSION}/libvieilleversion-0.1.0.

Un bon exemple de recette multiversion est b/libpng/libpng.recette.

Les répertoires /usr/share/doc et /usr/share/man ne doivent tout simplement PAS exister dans le paquet. La présente fonction s'occupe de déplacer tout répertoire '/usr/share/doc' dans /usr/doc/${NAMETGZ}-${VERSION}. En revanche, on tolère les répertoires comme par exemple /usr/share/vim/doc, et plus généralement tant que les paquets ont leur propre arborescence. On prendra aussi soin de créer un lien sous /usr/doc/paquet-version vers /usr/share/gtk-doc/paquet le cas échéant.


creer_post_installation

creer_post_installation crée le fichier spécial pour Spack ${PKG}/post-install.sh. C'est le script qui est exécuté juste après l'installation afin de configurer le logiciel, finaliser l'installation in situ, mettre à jour le système, etc.

Il détecte automatiquement si des fichiers *.0nouveau sont présents et crée le script permettant de comparer avec des fichiers déjà installés sur le système et le cas échéant d'éviter l'écrasement de fichiers de configuration. Ainsi, pour créer un fichier qui ne doit pas écraser un fichier portant le même nom (par exemple, httpd.conf) lors d'une mise à niveau, il suffit de lui ajouter l'extension .0nouveau (par exemple httpd.conf.0nouveau). Ce sera à l'utilisateur de vérifier s'il veut migrer vers le fichier en .0nouveau ou pas. Si oui, il supprimera l'extension .0nouveau et écrasera son ancien fichier, sinon, soit il ne fera rien, soit il supprimera le fichier .0nouveau (idéalement).

Cette fonction s'occupe également d'ajouter toutes les fonctions de réindexation, mise à jour etc. dans ce même script (icônes à réindexer, polices à réindexer, raccourcis bureau à mettre à jour, types MIME à mettre à jour, bibliothèques à ajouter à l'éditeur de liens via ldconfig, mise à jour des dépendances entre modules noyau, etc.). Voyez les sources du fichier de fonctions dans 0Linux/a/0outils/fonctions_paquets.sh pour plus de détails).

On ajoutera donc à loisir manuellement d'autres fonctions au script ${PKG}/post-install.sh, notamment des permissions spéciales ou des commandes particulières via de simples echo ou cat (via la syntaxe « heredoc », voyez en fin de page).

:!: Notez bien que la racine doit être supprimée de tout chemin de fichier si chroot n'est pas utilisé, afin de respecter une éventuelle option –root=/quelque/part passée à Spack lors de l'installation du paquet. Ainsi, on n'écrira pas :

chown shadow:root /var/lib/shadow # NON !
chown shadow:root ${PKG}/var/lib/shadow # NON !

Mais bien :

chown shadow:root var/lib/shadow # OUI :)

stripper

stripper s'occupe de supprimer les nombreux symboles de débogage dans les fichiers compilés. À noter que certains paquets détestent qu'on les strip !


empaqueter

empaqueter appelle spackpkg pour empaqueter tout le répertoire ${PKG}, passer toutes les permissions du paquet à root:root (attention donc à bien ajouter les permissions spéciales dans le script de post-installation) et nettoyer derrière-lui en supprimant $NAME et $PKG. La fonction utilise fakeroot pour ne pas avoir à empaqueter en tant que root.

Cette fonction procède également à de nombreuses vérifications et s'occupe de créer un fichier contenant les dépendances de chaque exécutable dans un fichier /usr/doc/PAQUET-VERSION/ldd.log, compresse les manuels, place la description, etc. Le plus parlant reste de lire le script fonctions_paquets.sh ; il contient de nombreux commentaires.


La compilation

Elle se trouve après preparer_sources car on est à ce moment-là dans les sources décompactées et préparées.

./configure --help

…pour consulter les options spécifiques au paquet.

On tente ensuite le ./configure && make :

CFLAGS="${FLAGS}" CXXFLAGS="${FLAGS}" \
./configure \
	--prefix=/usr \
	--sysconfdir=/etc \
	--localstatedir=/var \
	--libdir=/usr/lib${LIBDIRSUFFIX} \
	--mandir=/usr/man \
	--infodir=/usr/info \
	--docdir=/usr/doc/${NAMETGZ}-${VERSION} \
	--build=${PKGARCH}-0linux-linux-gnu
 
make -j${JOBS} || make

Le nombre de tâches à exécuter en parallèle ${JOBS} est définie automatiquement par la fonction cflags, selon le nombre de processeurs présents sur l'hôte. Elle est égale à $(nproc) + 1. À noter que certains paquets n'aiment pas la parallélisation de make, on doit alors la désactiver par un simple appel à make ou make -j1.

Il faut aussi détecter quel paramètre s'occupe d'isoler le paquet du système pour le construire dans un répertoire dédié. C'est généralement le paramètre DESTDIR qui revient, mais une lecture du 'Makefile' ou autre permet de savoir si le paramètre ne serait pas plutôt INSTALL_ROOT, PREFIX ou autre :

make install DESTDIR=/tmp/quelque/part
make install install_prefix=/tmp/quelque/part
make install INSTALL_ROOT=/tmp/quelque/part
etc.

Recette générique standard

#!/usr/bin/env bash
. /usr/share/0outils/fonctions_paquets.sh
 
NAMESRC=LibTruc
VERSION=0.1.2.3.4
EXT=tar.xx
NAMETGZ=libtruc
WGET=http://ftp.gnu.org/gnu/$NAMESRC/$NAMESRC-$VERSION.$EXT
DESC="Des bibliothèques et outils pour faire fonctionner quelque chose de précis..."
EXTRADEPS="libtruc libmachin gconf xproto"
 
telecharger_sources
preparer_sources # À partir d'ici, on se trouve dans les sources décompactées.
cflags
 
# Compilation :
CFLAGS="${FLAGS}" CXXFLAGS="${FLAGS}" \
./configure \
	--prefix=/usr \
	--sysconfdir=/etc \
	--localstatedir=/var \
	--libdir=/usr/lib${LIBDIRSUFFIX} \
	--mandir=/usr/man \
	--infodir=/usr/info \
	--docdir=/usr/doc/${NAMETGZ}-${VERSION} \
	--build=${PKGARCH}-0linux-linux-gnu
 
make -j${JOBS} || make
fakeroot make install DESTDIR=${PKG}
 
installer_doc
creer_post_installation
stripper
empaqueter
 
# C'est fini.

Recette multilib pour x86_64

Voici une recette qu'on rencontre assez souvent sous 0Linux x86_64, c'ets la recette multilib, contenant les versions 32 bits et 64 bits d'un même paquet. Voyons un exemple avec libidn.

On a là une recette multilib sommes toutes assez classique. Remarquez qu'on appelle cflags pour définir l'architecture détectée (ici x86_64), afin d'appeler à nouveau cflags i686 pour compiler en 32 bits sur un hôte en 64 bits. Puis on recompile en 64 bits. Les fichiers installés par l'étape 64 bits écraseront ceux installés par l'étape 32 bits. Les plus curieux auront remarqué qu'on appelle preparer_sources 3 fois en tout, ce qui est sinon une erreur, du moins une maladresse.

#!/usr/bin/env bash
. /usr/share/0outils/fonctions_paquets.sh
 
VERSION=1.29
WGET=http://ftp.gnu.org/gnu/$NAMESRC/$NAMESRC-$VERSION.tar.gz
DESC="Bibliothèques pour noms de domaine internationalisés"
 
telecharger_sources
preparer_sources # À partir d'ici, on se trouve dans les sources décompactées.
cflags
 
# On compile les bibliothèques 32 bits pour le multilib sous x86_64 :
if [ "${PKGARCH}" = "x86_64" ]; then
 
	# On passe en 32 bits (CFLAGS, LIBDIRSUFFIX, PKGARCH et Cie) :
	cflags i686
 
	# Compilation pour i686 :
	CFLAGS="${FLAGS}" CXXFLAGS="${FLAGS}" \
	./configure \
		--prefix=/usr \
		--sysconfdir=/etc \
		--localstatedir=/var \
		--libdir=/usr/lib${LIBDIRSUFFIX} \
		--mandir=/usr/man \
		--infodir=/usr/info \
		--docdir=/usr/doc/${NAMETGZ}-${VERSION} \
		--build=${PKGARCH}-0linux-linux-gnu
 
	make -j${JOBS} || make
	fakeroot make install DESTDIR=${PKG}
fi
 
# On refait la préparation des sources, il peut rester des déchets de la
# compilation en 32 bits (et make 'distclean' ne fonctionne pas toujours) :
preparer_sources # À partir d'ici, on se trouve dans les sources décompactées.
cflags
 
# Compilation :
CFLAGS="${FLAGS}" CXXFLAGS="${FLAGS}" \
./configure \
	--prefix=/usr \
	--sysconfdir=/etc \
	--localstatedir=/var \
	--libdir=/usr/lib${LIBDIRSUFFIX} \
	--mandir=/usr/man \
	--infodir=/usr/info \
	--docdir=/usr/doc/${NAMETGZ}-${VERSION} \
	--build=${PKGARCH}-0linux-linux-gnu
 
make -j${JOBS} || make
fakeroot make install DESTDIR=${PKG}
 
installer_doc
creer_post_installation
stripper
empaqueter
 
# C'est fini.

Recette minimaliste

Avec un peu de chance, on peut tomber sur un paquet qui contient une procédure parfaitement standard (configure ; make ; make install). Allégée des variables facultatives, on peut arriver à une recette comme suit :

#!/usr/bin/env bash
. /usr/share/0outils/fonctions_paquets.sh
 
VERSION=0.1.2.3.4
WGET=http://ftp.gnu.org/gnu/$NAMESRC/$NAMESRC-$VERSION.tar.gz
DESC="Des bibliothèques et outils pour faire fonctionner quelque chose de précis..."
 
telecharger_sources
preparer_sources # À partir d'ici, on se trouve dans les sources décompactées.
cflags
configure_make_makeinstall
installer_doc
creer_post_installation
stripper
empaqueter
 
# C'est fini.

Recette générique avec ajouts manuels

La recette suivante est multiversion, elle ajoute des commandes à la post-installation, désactive la parallélisation, ajoute un drapeau à ${FLAGS}, une option au ./configure et au make install, renomme un fichier de configuration pour ne pas en écraser un plus ancien et en ajoute en fin de script :

#!/usr/bin/env bash
. /usr/share/0outils/fonctions_paquets.sh
 
NAMESRC=LibBidule
VERSION=0.1.2
EXT=tar.gz
NAMETGZ=libbidule
WGET=(http://truc.bidule/download/$NAMESRC/$NAMESRC-$VERSION.$EXT
      http://truc.bidule/download/$NAMESRC/$NAMESRC-0.1.0.$EXT
     )
DESC="Bibliothèques pour bidules, très pratique pour effectuer des opérations diverses et variées comme faire des choses, des machins, des trucs voire même des bidules. Le paquet contient la documentation ainsi que les symboles de débogage pour trucmucher en profondeur ainsi que la vielle version 0.1.0, incompatible avec l'actuelle mais néanmoins nécessaire. Voir le site http://www.truc.bidule"
 
telecharger_sources
cflags
 
# On compile la vielle version 0.1.0 en premier lieu :
preparer_sources $NAMESRC-0.1.0.$EXT
 
# Compilation :
./configure \
	--prefix=/usr \
	--sysconfdir=/etc \
	--localstatedir=/var \
	--libdir=/usr/lib${LIBDIRSUFFIX} \
	--mandir=/usr/man \
	--infodir=/usr/info \
	--docdir=/usr/doc/${NAMETGZ}-${VERSION} \
	--enable-bidule \
	--build=${PKGARCH}-0linux-linux-gnu
 
make -j${JOBS} || make
fakeroot make install MANDIR="/usr/man" DESTDIR=${PKG}
 
# On place la documentation dans un sous-répertoire dédié :
installer_doc ${NAMETGZ}-${VERSION}/${NAMETGZ}-0.1.0
 
# On compile à présent la version normale de le recette :
preparer_sources # À partir d'ici, on se trouve dans les sources décompactées.
 
# Il faut un répertoire dédié à la compilation :
mkdir $TMP/bidule-build && cd $TMP/bidule-build
 
# Compilation :
CFLAGS="${FLAGS} -g" CXXFLAGS="${FLAGS} -g" \
/$TMP/${NAME}/configure \
	--prefix=/usr \
	--sysconfdir=/etc \
	--localstatedir=/var \
	--libdir=/usr/lib${LIBDIRSUFFIX} \
	--mandir=/usr/man \
	--infodir=/usr/info \
	--docdir=/usr/doc/${NAMETGZ}-${VERSION} \
	--enable-bidule \
	--build=${PKGARCH}-0linux-linux-gnu
 
cd -
 
make -j1
fakeroot make install MANDIR="/usr/man" DESTDIR=${PKG}
 
# On renomme ce fichier de configuration pour ne pas en écraser un plus ancien sur le système :
mv ${PKG}/etc/bidule/bidule.conf{,.0nouveau}
 
installer_doc
 
# On complète la documentation :
cp -a LISEZMOI HOWTOBUILD contrib.txt docs ${PKG}/usr/doc/${NAMETGZ}-${VERSION}/
 
creer_post_installation
 
# On complète la post-installation :
cat >> ${PKG}/post-install.sh << "EOF"
chown bidule:root var/lib/bidule*
chmod -R 700 var/lib/bidule*
 
EOF
 
# On se strippe rien pour conserver les symboles de débogage :
# stripper
 
empaqueter
 
# C'est fini.

Je veux tout faire à la main !

Et ça se comprend ! C'est très simple, il suffit d'écrire ce qu'on ferait manuellement dans un terminal pour compiler un logiciel. Il faut penser également à la post-installation éventuelle (mettre à jour le cache des icônes, par exemple) à placer dans le fichier post-install.sh et ajouter une description courte du logiciel dans un fichier about.txt. voici donc un exemple de recette manuelle qui donnera un paquet Spack tout à fait correct :

#!/usr/bin/env bash
 
# On télécharge le logiciel :
wget ftp://ftp.gnu.org/gnu/libtruc/libtruc-1.2.3.tar.gz
 
# On déballe et on se place dans les sources :
tar xf libtruc-1.2.3.tar.gz
cd libtruc-1.2.3
 
# On compile tout ça de manière classique :
./configure --prefix=/usr --libdir=/usr/lib64
make
 
# On installe dans un répertoire dédié en se faisant passer pour root :
fakeroot make install DESTDIR=/tmp/build/libtruc-1.2.3
 
# On ajoute une description :
echo "libtruc: libtruc (Une lib pour faire des trucs)" > /tmp/build/libtruc-1.2.3/about.txt
 
# On ajoute une post-installation le cas échéant. Ici, une mise à jour du cache des icônes GTK+ :
echo "chroot . /usr/bin/gtk-update-icon-cache -f -t /usr/share/icons/hicolor >/dev/null 2>&1" > /tmp/build/libtruc-1.2.3/post-install.sh
 
# On n'a plus qu'à empaqueter le répertoire dédié /tmp/build/libtruc-1.2.3.
# On seplace dedans :
cd /tmp/build/libtruc-1.2.3
 
# On appelle spackpkg sur le répertoire courant (« . ») en se faisant passer pour root :
fakeroot /usr/sbin/spackpkg . /usr/local/paquets/libtruc-1.2.3-x86_64-1
 
# C'est fini.

Appelons ce script comme on veut, mais de façon plus logique, appelons-le libtruc.recette et rendons-le exécutable :

chmod +x libtruc.recette

On n'a plus qu'à l'exécuter :

./libtruc.recette

Le paquet créé dans /usr/local/paquets/ n'a plus qu'à être installé avec spackadd. Il sera désinstallable avec spackrm.

Pour le mettre à jour ou le corriger plus tard, on peut éditer ce script puis remplacer libtruc-1.2.3-x86_64-1 par libtruc-1.2.3-x86_64-2 et spackadd gèrera la mise à niveau du paquet vers cette révision.


Créer un paquet-abonnement

Les paquets-abonnements remplacent les anciens « dépôts » de 0Linux I, II et zeta et permettent de regrouper un ensemble de logiciels sous forme d'abonnement (par exemple, tout KDE, GIMP et ses greffons, un ensemble d'applications pour serveur Web, studio multimédia, etc.). Ils se nomment obligatoirement avec un suffixe « -abonnement » et leur recette est nommé ainsi : nom-abonnement.recette.

Les sources de 0Linux, contenues dans une arborescence géré par git (voir la page des téléchargements), contiennent des fichiers exemples (notamment le fichier generique-abonnement.recette) ainsi que de multiples recettes sous z/ dont on peut et devrait s'inspirer. Voyez plus bas dans cette page pour une explication sur la syntaxe de la description du paquet-abonnement.


Recette générique d'un paquet-abonnement

#!/usr/bin/env bash
. /usr/share/0outils/fonctions_paquets.sh
 
NAMETGZ=truc-abonnement # Le « -abonnement » est absolument OBLIGATOIRE pour se différencier des paquets normaux
VERSION=1 # La version sert pour les ajouts/suppressions de paquets, modif' de description, etc.
DESC="Le gestionnaire de machins TRUC3, ses plugins et son SDK complet"
EXTRADEPS="libtruc libmachin gconf xproto truc-tools truc-plugins truc-sdk"
 
cflags
 
# On place la description de l'abonnement (en txt2tags) :
cat > ${TMP}/${NAMETGZ}.t2t << EOF
Description de l'abonnement $NAMETGZ
appzer0 - appzer0@free.fr
Mai 2013
 
= TRUC3, une plateforme truquée =
 
TRUC3 est une plateforme permettant à tout un chacun de faire des trucs, des bidules voire des machins, grâce à un SDK complet et une doc complète pleine de choses autres joyeusetés.
 
= L'abonnement $NAMETGZ pour 0linux =
 
L'abonnement contient le moteur de TRUC, tous ses plugins, un kit de développement ainsi que plusieurs bibliothèques bien utiles pour faire des trucs (graphismes, sons, etc.).
 
= Installation sous 0linux =
 
``# 0g ${NAMETGZ}``
 
= Liste des paquets inclus dans l'abonnement =
 
EOF
 
# On ajoute la liste des paquets en dépendances à la description :
rm -f $TMP/xdeps.tmp
for d in ${EXTRADEPS}; do
	echo ${d} >> $TMP/xdeps.tmp
done
cat $TMP/xdeps.tmp | sort >> ${TMP}/${NAMETGZ}.t2t
 
# On génère la description dans les différents formats :
mkdir -p ${PKG}/var/log/0abonnements
for format in html txt; do
	txt2tags --encoding=UTF-8 -t ${format} -o ${PKG}/var/log/0abonnements/${NAMETGZ}.${format} ${TMP}/${NAMETGZ}.t2t
done
 
empaqueter
 
# C'est fini.

Le plus important d'une recette-abonnement est la variable EXTRADEPS : c'est ici qu'on va placer tous les paquets qu'on va forcer à installer en même temps que le paquet-abonnement. Par exemple, si l'on désire créer un abonnement pour une utilisation de type « studio graphique et PAO », on ajoutera à la variable EXTRADEPS les paquets gimp, inkscape, scribus, krita et mypaint et on appellera la recette, disons, studio-pao-abonnement.recette afin de fournir un ensemble d'applications propices à l'exploitation d'une station de travail dédiée au graphisme et à la publication assistée par ordinateur (ou « PAO »), les possibilités sont infinies.


Description des abonnements

Les paquets-abonnements contiennent des descriptions écrites en txt2tags pour permettre sa conversion en de nombreux formats, comme le texte, le HTML ou la syntaxe pour wikis. On doit en respecter la syntaxe, qui est néanmoins très simple :

  • la première ligne contient le titre du document : « Description de l'abonnement $NAMETGZ »
  • la deuxième ligne contient le nom ou pseudonyme du créateur ou mainteneur du paquet-abonnement, suivi d'un tiret entre espaces et de son adresse e-mail
  • la troisième ligne contient la date de dernière modification, généralement le mois et l'année, le format n'a pas d'importance
  • Ensuite viennent 3 paragraphes avec chacun un titre, concernant respectivement la description elle-même, puis une description de l'abonnement lui-même (paquets supplémentaires, documentation, modifications par rapport au logiciel original, bref toute précision utile au lecteur), puis un exemple de la commande 0g à invoquer pour s'abonner.
Description de l'abonnement $NAMETGZ
appzer0 - appzer0@free.fr
Mai 2013
 
= TRUC3, une plateforme truquée =
 
TRUC3 est une plateforme permettant à tout un chacun de faire des trucs, des bidules voire des machins, grâce à un SDK complet et une doc complète pleine de choses autres joyeusetés.
 
= L'abonnement $NAMETGZ pour 0linux =
 
L'abonnement contient le moteur de TRUC, tous ses plugins, un kit de développement ainsi que plusieurs bibliothèques bien utiles pour faire des trucs (graphismes, sons, etc.).
 
= Installation sous 0linux =
 
``# 0g ${NAMETGZ}``
 
= Liste des paquets inclus dans l'abonnement =

La liste des paquets sera remplie automatiquement par la recette.