Bonjour à tous,

Ça faisait longtemps que je n'ai pas fait un mail de 10 pages, alors en voici 
un ! :-)

Le développement de Ncooker avance et il reste un fichier des NBUILDs pour 
lequel je voudrais apporter des améliorations : le fichier build.

Pour rappel, ce fichier est un script bash contenant un ensemble de fonctions 
dont le nom commençe par do_*. Chacune d'elles représente une étape du 
processus de compilation du NBUILD qui va permettre d'obtenir un paquet NBA. 
Elles contiennent les instructions permettant de réaliser l'étape 
correspondante. Ces fonctions sont appelées l'une après l'autre par Ncooker, 
et il est possible de n'exécuter que certaines d'entre elles, ce qui est bien 
pratique durant la mise au point d'un NBUILD.

Voici rapidement la liste de ces fonctions utilisables actuellement, et leur 
rôle, dans l'ordre où elles sont appelées :

- do_preconfig() : cette fonction est utilisée pour appliquer des patches aux 
fichiers sources et/ou à modifier des fichiers à l'aide sed ou awk par 
exemple. Plus généralement, elle permet de modifier certains paramètres avant 
que l'environnement de compilation soit généré.

- do_config() : cette fonction lance le script ./configure avec les options 
voulues, ce qui a pour effet de préparer l'environnement de compilation.

- do_premake() : cette fonction peut être utilisée pour modifier les fichiers 
générer par le script ./configure ou configurer certaines choses à la main 
qui n'ont pas été faite par ./configure. Plus généralement, elle permet de 
terminer la préparation de l'environnement de compilation.

- do_make() : cette fonction se contente généralement de lancer la commande 
« make », éventuellement avec des paramètres, pour procéder à la compilation 
de l'application.

- do_preinstall() : cette fonction permet de préparer l'environnement pour 
installer l'application dans un fakeroot, un dossier utilisé comme s'il 
s'agissait de la racine de l'arborescence du système. Dans beaucoup de 
paquets actuels, elle est utilisée pour copier des fichiers d'informations 
(AUTHOR, README, NEWS, CHANGELOG ...) dans le fakeroot. Perso, je trouve que 
cela aurait plus sa place dans la fonction do_postinstall() (voir plus loin).

- do_install() : cette fonction procède à l'installation de l'application dans 
le fakeroot. Elle fait généralement appel à la commande « make 
DESTDIR=$INST_ROOT install » où la variable $INST_ROOT, positionnée par 
Ncooker, contient le chemin d'accès au fakeroot.

- do_postinstall() : cette fonction permet de « finaliser » l'installation, ce 
qui représente une notion assez large :-) . Tout dépend ici des besoins de 
l'application. Il peut s'agir par exemple de créer un fichier de 
configuration par défaut.
Elle sert aussi à nettoyer les fichiers objets (binaires et librairies) de 
leurs symboles (comme les symboles de débuggage par exemple), ce qui permet 
de réduire leur taille.
Elle est également utilisée pour copier les ressources incorporées au NBUILD 
dans le fakeroot, comme un fichier *.desktop par exemple.
Dans certains paquets, elle est aussi utilisée pour déclarer les fichiers dits 
« sensibles », comme les fichiers de configuration, qu'il sera possible de 
préserver lors d'une mise à jour du paquet pour éviter qu'ils soient écrasés.

- do_package() : c'est la fonction qui génère le paquet NBA. Elle fait appel à 
la commande makenpkg2 pour créer un fichier .tgz avec ce qui se trouve dans 
le fakeroot. Cette commande génère des informations supplémentaires comme la 
liste des fichiers contenant le .tgz, la liste des dépendances nécessaires au 
bon fonctionnement de l'application, etc. Tout ceci est regroupé pour former 
un paquet NBA.


Il reste une dernière fonction, do_static(), qui n'est pas obligatoire, et qui 
sert à compiler l'application en mode « statique », c'est à dire en 
incorporant directement dans le fichier binaire de l'application le code des 
librairies de fonctions utilisées (en gros, hein :-) ). Elle n'est appelée 
que si on invoque Ncooker avec une option spéciale, et remplace alors la 
fonction do_make(). Si je ne me trompe pas, elle est utilisée pour faire le 
devkit. Il faudrait savoir si elle est toujours nécessaire (Riri ?).

Toutes ces fonctions, à part do_static(), sont obligatoires dans le fichier 
build, _même_ si elles ne sont pas nécessaires pour la bonne compilation de 
l'application. Dans le cas où une fonction n'a pas besoin d'être utilisée, il 
suffit de placer un « echo "Nothing to do." » dans son corps pour indiquer 
qu'il n'y a rien à faire à cette étape.

Voilà pour ce qui est du rappel :-) (n'hésitez pas à compléter si j'ai oublié 
des choses)


Quelles sont les améliorations que je propose d'apporter ?

Tout d'abord, je voudrais étoffer un peu cette liste de fonctions pour obtenir 
ceci :

- do_uncompress()
- do_patches()
- do_preconfig()
- do_config()
- do_premake()
- do_make()
- do_check()
- do_preinstall()
- do_install()
- do_postinstall()
- do_packages()
- do_help()
- do_static() (?)

J'ai ajouté les quatre fonctions do_uncompress(), do_patches(), do_check() et 
do_help().
La première permet de réaliser soi-même la décompression des archives sources 
au lieu de laisser Ncooker le faire. Ça peut s'avérer utile avec certains 
paquets comme le driver Nvidia par exemple.
La seconde permet de séparer l'application des patches de la 
« préconfiguration » avec do_preconfig(). Autrement dit, do_preconfig() 
garderait son rôle actuel excepté l'application des patches, qui eux seraient 
faits dans do_patches(). L'intérêt d'une telle modification n'apparaît pas 
immédiatement, mais attendez la suite :-)
La troisième permet de lancer une vérification de la compilation. Cette 
fonctionnalité n'est pas présente dans tous les makefiles, mais lorsqu'elle 
l'est, un simple « make check » permet de lancer une série de tests pour 
valider que l'application s'est compilée correctement. C'est particulièrement 
important pour les librairies de base du système.
La dernière enfin permet d'afficher des infos utiles pour compiler le paquet, 
comme les options utilisables avec ./configure par exemple.

Les plus attentifs auront remarqués que j'ai ajouté un « s » à la fonction 
do_package() :-) car je souhaite ajouter la possibilité de générer plusieurs 
NBAs à partir d'un seul NBUILD :-) C'est un autre sujet ...


Là où ça commence à devenir plus intéressant, c'est que _toutes_ ces 
fonctions, sans exception, seraient OPTIONNELLES ! C'est-à-dire que pour 
certains paquets, il ne serait pas nécessaire de fournir un fichier build 
pour générer un paquet NBA :-)
Comment cela est-il possible ? Tout simplement en intégrant à Ncooker un 
comportement par défaut, proche du fameux triplet de commandes « ./configure; 
make; make install » qui permet de compiler une très grande majorité 
d'applications.
L'idée est que pour chaque étape, Ncooker regarde si le fichier build contient 
une fonction associée. Si c'est le cas, il l'exécute, sinon, il utilise celle 
fournit par défaut avec la commande build. Puis il passe à la suivante en 
procédant de la même manière.

Examinons à nouveau toutes les étapes en utilisant ce procédé :

- Décompression des archives sources : Ncooker regarde si la fonction 
do_uncompress() existe. Si oui, il la lance, sinon il décompresse lui-même 
les archives dans le répertoire qui va bien.

- Application des patches : comme précédemment, Ncooker regarde si la fonction 
do_patches() existe et la lance le cas échéant. Sinon, il applique 
automatiquement les patches trouvés dans le répertoire /patches du nbuild.
Plusieurs choses peuvent être mises en place ici. D'abord, on pourrait classer 
les patches dans une arborescence :

patches/
   |_ x86/
   |_ x86_64/

Le répertoire patches/ pourrait contenir les patches à appliquer tout le 
temps, indifféremment de l'architecture matérielle du système. Le 
sous-répertoire x86/ contiendrait les patches à appliquer que pour les 
architectures 32bits, et x86_64/, uniquement ceux à appliquer pour les 
architectures 64bits. À charge pour Ncooker de déterminer automatiquement 
l'architecture matérielle.
Si cela s'avère nécessaire, on peut créer des sous-répertoires dans x86 (et 
x86_64) pour les patches spécifiques à certains microprocesseurs. Par 
exemple,

patches/
   |_ x86/
       |_ pentium4
       |_ athlon-xp

Si le microprocesseur est un athlon-xp, les patches appliqués seraient ceux 
qui se trouvent dans les répertoires patches/, patches/x86/ et 
patches/x86/athlon-xp/.
Là encore, à charge pour Ncooker de déterminer le type de microprocesseur.

Si les patches sont compressées, ils sont automatiquement décompressés avant 
utilisation.
Quant aux options à utiliser par défaut avec la commande « patch », j'ai 
décortiqué les paquets fournis avec nasgaia 1.0.1, et le plus souvent, ce 
sont les options « -Np1 -i » qui sont utilisées. Je propose donc de les 
adopter par défaut. Certains paquets utilisent l'option « -p2 » au lieu de 
« -p1 ». Dans ce cas, soit on écrit la fonction do_patches() dans le fichier 
build pour appliquer soi-même le patch, soit on modifie le patch pour qu'il 
n'y ait qu'un seul niveau à supprimer dans le chemin du fichier (« man 
patch » pour ceux qui ont du mal à suivre ;-) )

- do_preconfig() : le comportement par défaut de Ncooker ne fait rien.

- do_config() : S'il n'y a pas de fonction do_config() dans le fichier build, 
Ncooker recherche un script ./configure exécutable. S'il le trouve il 
l'exécute. Ok, mais avec quelles options par défaut ? :-) Ici, il n'est pas 
possible de choisir des options par défaut qui soient vraiment 
« passe-partout » ... Qui plus est, je me souviens que quelqu'un avait déjà 
émis le souhait de pouvoir savoir qu'elles sont les options de ./configure 
utilisées par défaut dans les nbuilds. Je propose une solution pour répondre 
aux deux problèmes en même temps : utiliser une variable NPKG_CONFIG_OPTIONS 
dans le fichier « infos » du nbuild. Par exemple :

NPKG_CONFIG_OPTIONS="--prefix=/usr --with-ssl"

Le comportement par défaut de Ncooker serait alors de lancer « ./configure 
$NPKG_CONFIG_OPTIONS ». D'un autre coté, la commande « Ncooker info 
paquet.nbuild » montrerait, entre autres, les options utilisées par défaut 
avec ./configure en affichant simplement la valeur de la variable 
NPKG_CONFIG_OPTIONS. 
Bien sûr, la commande « Ncooker build » proposerait une option pour permettre 
à l'utilisateur de surpasser les options par défaut. Par exemple :

$ Ncooker build --config-options "--without-ssl" paquet.nbuild

La commande lancée par Ncooker serait alors :

./configure $NPKG_CONFIG_OPTIONS <options passées à --config-options>
soit :
./configure --prefix=/usr --with-ssl --without-ssl

la dernière option annulant l'effet de la seconde.

- do_premake() : le comportement par défaut de Ncooker de fait rien.

- do_make() : le comportement par défaut de Ncooker est de lancer la commande 
« make ». Là aussi, on peut utiliser une variable NPKG_MAKE_OPTIONS dans le 
fichier « infos » pour définir des paramètres à utiliser avec make + une 
option spéciale pour la commande «  Ncooker build ».

- do_ckeck() : le comportement par défaut de Ncooker est de faire un grep sur 
le fichier Makefile pour recherche une entrée « check: » ou «  test: ». S'il 
en trouve une, il lance la commande « make » qui correspond (make check ou 
make test).

- do_preinstall() : le comportement par défaut de Ncooker ne fait rien.

- do_install() : le comportement par défaut de Ncooker est de lancer la 
commande « make DESTDIR=$INST_ROOT install ». Parfois, il faut utiliser une 
autre variable que DESTDIR. Il faut voir s'il y a un moyen de la trouver 
automatiquement. Sinon, il faudra écrire la fonction do_install() dans le 
fichier build directement.

- do_postinstall() : Le comportement par défaut de Ncooker est de supprimer 
les symboles des fichiers objets, et de placer un certains nombres de fichier 
d'informations (AUTHOR, README, NEWS, CHANGELOG ...) dans le 
répertoire /usr/share/doc/<nom-appli> du fakeroot s'ils existent.

- do_packages() : Pour ce qui est de la création des paquets NBAs, je pense 
qu'il faut en parler sur un thread à part :-) Dans tous les cas, le 
comportement par défaut de Ncooker est de créer un seul paquet NBA.

- do_help() : le comportement par défaut est d'exécuter ./configure --help 
si ./configure existe, et/ou d'afficher le fichier README/INSTALL s'ils 
existent.


Voilà pour l'idée de base :-)
La création d'un paquet nbuild serait ainsi grandement facilitée :
* dans le meilleur cas, il n'y a pas de fichier build à écrire, seules les 
variables NPKG_CONFIG_OPTIONS et NPKG_MAKE_OPTIONS doivent être définies dans 
le fichier « infos » (c'est Geekitus qui va être content ;-) )
* Le cas intermédiaire est que seules certaines fonctions par défaut de 
Ncooker conviennent pour compiler le paquet, mais pas d'autres. Il suffit 
alors de réécrire dans le fichier build uniquement les fonctions par défaut 
qui ne vont pas.
* Le pire cas est bien sûr de devoir réécrire toutes les fonctions parce le 
comportement par défaut de Ncooker n'est absolument pas adapté.

Cette solution présente aussi l'avantage de laisser la liberté au nbuildeur 
d'écrire l'ensemble des fonctions du fichier build s'il le souhaite, 
indépendamment du fait que le comportement par défaut de Ncooker puisse ou 
non convenir pour son paquet.


Si vous avez bien assimiler cette proposition, passons à l'étape 
supérieure :-) : le couple autoconf/automake n'est pas la seule manière de 
compiler une application. Il existe d'autre solutions comme Scons par 
exemple. Une idée pour rendre Ncooker encore plus pratique/souple serait que 
la commande build ne dispose pas uniquement d'un comportement par défaut pour 
autoconf/automake, mais soit livrée avec un comportement par défaut pour les 
outils de construction les plus utilisés. Il détecterait automatiquement 
l'outil utilisé et sélectionnerait le comportement par défaut 
correspondant :-) ...


Voilà, dites-moi ce que vous pensez de tout ça ;-)

++
Gontran

Répondre à