Autoconf / Automake en 10 étapes

Autant le dire tout de suite, je ne suis pas trop fan de la solution autoconf/automake qui permet de générer un script pour compiler et installer vos programmes C/C++ open-source. Malgré tout, dans certains cas, cette solution a son intérêt ou peut même devenir nécessaire. Cela m’a bien servi notamment pour faire le portage de DKB Trace pour Synology.

Il faut reconnaître que la plupart des sites traitant du sujet s’attachent trop à lister les fonctionnalités d’autoconf/automake et se perdent dans l’utilisation concrète. Je suis tombé malgré tout sur un tutoriel en anglais(1) traitant du sujet et j’en ai profité pour revisiter le sujet… en 10 étapes 🙂

Les pré-requis

On va partir de l’hypothèse que vous êtes sous Ubuntu (si vous êtes orienté open-source, cela a du sens:)), et que vous n’avez pas encore installé la suite « autotools ». Pour cela, voici ce qui est nécessaire de lancer à partir de votre terminal:

Installation d’autoconf :

$ sudo apt-get install autoconf

Installation d’autotools :

$ sudo apt-get install autotools-dev

L’autre hypothèse est qu’on part d’une structure projet avec une arborescence un peu moins bateau qu’un simple répertoire où se trouvent toutes les sources de votre programme. La voici :

src           : le répertoire où se trouvent vos sources
doc           : votre documentation en un ou plusieurs fichiers
web           : des scripts web type PHP    
    web/css   : des fichiers CSS    
    web/js    : des fichiers javascript
    web/fonts : des polices de caractères
examples      : des fichiers qui peuvent servir à votre programme

Aide : si jamais vous n’avez pas d’exemple de programme C sous la main, vous pouvez partir de l’exemple fourni en format tar.gz :  HelloDigitalBoxBegin. Une fois le fichier téléchargé, désarchivez-le via le terminal :

tar -xvf HelloDigitalBoxBegin.tar.gz

Dans beaucoup de projets open-source en C/C++, l’installation à partir des fichiers sources s’effectue souvent en 3 phases :

$ configure
$ make
$ sudo make install

La première consiste à détecter les caractéristiques de votre environnement et générer le ou les fichiers makefile. La deuxième phase lance la construction de votre programme (compilation et linking). La dernière déplace les fichiers utiles de votre programme pour réaliser l’installation sur la machine.

Maintenant que tout cela est dit, passons à l’étape 1.

1. Faire du ménage

1-menage

Un peu de ménage c’est un bon début! Pour cela allez dans le répertoire de votre projet C et renommez votre fichier makefile existant car celui-ci va être reconstruit automatiquement par la suite.

Si vous partez du projet HelloDigitalBoxBegin, vous n’aurez rien à faire à ce niveau, à part aller dans le répertoire car aucun makefile n’est présent (cerise sur le gateau).

$ cd HelloDigitalBoxBegin

2. Générer le fichier configure.ac

2-generer-fichier

Pour cela lancez autoscan depuis la racine de votre répertoire projet :

$ autoscan

Cet utilitaire génère automatiquement un fichier « configure.scan » en faisant une analyse des fichiers de votre répertoire. C’est suffisant pour cette deuxième étape, et vous avez juste à le renommer en « configure.ac » puis à supprimer le fichier de log généré :

$ mv configure.scan configure.ac
$ rm autoscan.log

3. Ajuster la chose…

3-ajuster

Modifiez le contenu du fichier configure.ac avec votre éditeur favori (ici vim, mais si vous préférez geany, je ne vous en voudrai pas…) :

$ vim configure.ac

Modifiez la ligne suivante :

AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])

Par :

AC_INIT([HelloDigitalBox], [1.0], [bugreport@digitalbox.com])

Supprimez ensuite les 2 lignes juste en dessous qui ne servent pas  :

AC_CONFIG_SRCDIR([src/hello.c])
AC_CONFIG_HEADERS([config.h])

Si vous partez d’un autre projet que celui proposé, il pourrait y avoir d’autres ajustements à faire dans ce fichier.

C’est bon ? Voici la suite…

4. Générer un premier configure

4-configure

Vous êtes prêt pour produire le fameux script « configure » en lançant :

$ autoconf

Cette commande génère deux fichiers : autom4te.cache et configure.

Le premier est un répertoire utilisé pour accélérer le travail des autotools et pourra être supprimé lorsque vous fournirez votre package final.

Le deuxième fichier est le script qui sera lancé par un futur utilisateur de votre package 🙂

Pour l’instant celui-ci reste basique mais il va être complété par les étapes suivantes.

5. Produire les Makefile.am

5-makefile

Cette étape demande un peu plus de travail, car l’arborescence du projet présenté a été délibérément complexifiée.

Toutes les étapes avant ont permis de construire la partie qui va vérifier les pré-requis pour la construction de votre programme. Nous allons maintenant aborder comment va se construire votre programme, et comment il va s’installer.

Il s’agit en fait d’une coopération entre automake et autoconf pour compléter l’ensemble.

Automake génère des templates et le script généré par autoconf traduira ces templates en Makefile finaux. Ce n’est pas clair ? Alors action 🙂

Pour la racine :

Construisez d’abord votre fichier pour automake à la racine de votre projet (d’où l’extension « am » signifiant automake) :

$ vim Makefile.am

Ce fichier va se limiter à 2 lignes :

AUTOMAKE_OPTIONS = foreign
SUBDIRS = src examples doc web

La première vous simplifiera la vie en évitant de devoir produire des fichiers supplémentaires considérés comme des standards GNU (README et compagnie..)

La deuxième indique les différents répertoires de votre projet car ceux-ci vont devoir être explorés un à un.

Par la suite, nous allons devoir produire un fichier Makefile.am dans chaque répertoire :  automake va parcourir chacun d’eux afin de générer un fichier Makefile.in : ces fichiers « .in » seront exploités par le script autoconf pour produire les Makefiles finaux. Ouf !

Voici les 4 Makefile.am à produire:

Pour les sources :

Editez le fichier src/Makefile.am:

$ vim src/Makefile.am

Et insérez les lignes suivantes :

bin_PROGRAMS = hello_digitalbox
include_HEADERS = util.h hello.h 
hello_digitalbox_SOURCES = util.c hello.c
hello_digitalbox_LDADD = -lm

bin_PROGRAMS va indiquer le nom de votre exécutable qui sera généré alors que include_HEADERS liste l’ensemble des fichiers includes.

hello_digitalbox_SOURCES donne l’ensemble de vos fichiers sources nécessaires. Précision importante : le tiret est interdit dans le nom de votre programme, par exemple « hello-digitalbox » ne fonctionnera pas alors que « hello_digitalbox » si.

Enfin une option bien utile : hello_digitalbox_LDADD va indiquer l’option à utiliser au moment de la liaison (linkage) de vos différents modules (util.o et hello.o). Pourquoi ? Pour utiliser  la bibliothèque mathématique car le projet donné en exemple utilise la fonction racine carrée « sqrt ».

Pour les connaisseurs : pourquoi ne par utiliser l’option LDFLAGS comme-ci dessous pour le linker (et précédé par CFLAGS pour les options du compilateur) ?

CFLAGS = --pedantic -Wall -std=c99 -O2
LDFLAGS = -lm

La raison est simple : dans certains cas, les compilateurs C/C++ sont sensibles à l’ordre dans lequel l’option « -lm » de liaison apparaît. LDADD permet d’ajouter cette option A LA FIN de la ligne de commande (LDFLAGS les ajoute au début), ce qui dans le cas du portage de logiciel open-source peut résoudre un plantage sur la résolution des liens avec des bibliothèques.

Pour la documentation

Occupons-nous de la documentation :

$ vim doc/Makefile.am

Insérez la ligne suivante :

dist_doc_DATA = OVERVIEW

Automake déduira de cette ligne que le fichier OVERVIEW fait partie de votre documentation à installer.

Pour la partie web

Editez le fichier correspondant :

$ vim web/Makefile.am

Et ajoutez :

hello_digitalboxdir = $(datadir)/$(PACKAGE)/web
hello_digitalbox_DATA = info.php

Le première ligne indique où se trouvera l’installation du contenu web (sans chercher à compiler quoi que ce soit) et la deuxième précise les fichiers concernés : ici il y a juste un fichier « php ».

Si jamais vous avez une sous-arborescence dans votre répertoire web (par exemple du CSS, du javascript, des polices de caractères…), pas de soucis, la commande « nobase » est là pour vous : elle permettra de lister tous les fichiers contenus dans des sous-répertoires en gardant la structure des répertoires.

Par exemple tous les fichiers des répertoires « css », « js » et « fonts »  feront partie de l’installation si vous ajoutez la ligne ci-dessous (pour le projet d’exemple vous n’aurez pas à l’ajouter) :

nobase_hello_digitalbox_DATA = css/bootstrap-theme.css css/bootstrap-theme.css.map css/bootstrap-theme.min.css css/bootstrap-theme.min.css.map css/bootstrap.css css/bootstrap.css.map css/bootstrap.min.css css/bootstrap.min.css.map fonts/glyphicons-halflings-regular.eot fonts/glyphicons-halflings-regular.svg fonts/glyphicons-halflings-regular.ttf fonts/glyphicons-halflings-regular.woff fonts/glyphicons-halflings-regular.woff2 js/bootstrap.js js/bootstrap.min.js js/npm.js

Enfin pour les exemples :

Ces fichiers pourraient être des exemples nécessaires pour l’utilisation de votre programme. Par exemple dans le cas de DKB Trace, il s’agit de fichiers de description de scènes 3D.

Editez le fichier :

$ vim examples/Makefile.am

Avec le contenu suivant :

hello_digitalboxdir = $(datadir)/$(PACKAGE)/examples
hello_digitalbox_DATA = colors.dat shapes.dat skyvase.dat textures.dat

Il s’agit du même principe que pour le répertoire web : on indique où seront installés les fichiers (sans les compiler) et quels sont leurs noms.

Voilà une bonne étape de faite déjà !

6. Intégrer contrôles et construction (autoconf&automake)

6-control

Il faut maintenant insérer les macros dans le fichier configure.ac pour indiquer à autoconf que les fichiers Makefile devront être produit par le script « configure »:

$ vim configure.ac

Après AC_INIT(), il faut initialiser « automake » en ajoutant la ligne :

AM_INIT_AUTOMAKE

Ensuite autoconf doit générer un script « configure » qui produit les différents Makefiles. Toujours dans ce fichier, remplacez la ligne suivante :

AC_OUTPUT

Par celle-ci :

AC_OUTPUT(Makefile doc/Makefile examples/Makefile src/Makefile web/Makefile)

7. Configure & templates pour makefile

7-templates

Nous avons maintenant tout pour générer le fameux script « configure » lancé par les utilisateurs au moment de l’installation.

Voici comment procéder :

$ aclocal

Cela va générer un fichier aclocal.m4 qui contient les macros pour générer les éléments pour automake (i.e. AM_INIT_AUTOMAKE).

Ensuite :

$ automake --add-missing

Automake lit le « configure.ac » et le « Makefile.am » à la racine. Il les interprète et pour chaque Makefile.am produit un Makefile.in. L’option –add-missing indique à automake de fournir les scripts par défaut pour l’installation.

Enfin la prochaine étape pour construire configure :

$ autoconf

Le script « configure » est maintenant finalisé!

Lorsqu’il sera exécuté par un utilisateur, celui-ci effectuera la vérification des pré-requis de construction et générera aussi les Makefiles pour la construction.

8. Vérifier

8-verifier

Les scripts générés par automake (compile/depcomp/install.sh/missing) sont sous forme de liens dynamiques. La solution que j’ai trouvée pour pouvoir les inclure dans le package final est de supprimer le lien et de copier le fichier original dans le répertoire du projet.

Voici ce que cela donne sous Ubuntu (le répertoire peut varier avec par exemple comme répertoire source /usr/local/share/automake-1.15) :

$ rm compile
$ cp /usr/share/automake-1.15/compile ./compile
$ rm depcomp
$ cp /usr/share/automake-1.15/depcomp ./depcomp
$ rm install-sh
$ cp /usr/share/automake-1.15/install-sh ./install-sh
$ rm missing
$ cp /usr/share/automake-1.15/missing ./missing

$ rm -rf autom4te.cache/

La dernière ligne supprime des fichiers temporaires avant de produire votre package.

Et maintenant voici en détail l’utilisation des 3 commandes :

$ ./configure

Ce script va vérifier les dépendances avec les macros AC_* indiquées dans le fichier configure.ac. Si jamais il manque des éléments sur votre système, un message d’erreur apparaitrait.

Ensuite pour chaque Makefile indiqué dans AC_OUTPUT(), il va y avoir une transformation du template Makefile.in vers un Makefile final.

Le Makefile principal fournira les cibles les plus communes telles que : install, clean, distclean, uninstall.

Si configure se termine sans erreur alors c’est que tous les Makfeiles ont été générés !

Ensuite il faut taper :

$ make

Cette commande va lancer la construction complète de votre programme (compilation et liaison avec les bibliothèques). Pour le détail, celle-ci va utiliser comme point de départ la cible « all ».

Si cette étape se passe bien, vous allez pouvoir lancer le programme :

$ src/hello_digitalbox 
Hello Digital Box 7.0 !

Bravo!

Maintenant pour installer le programme, il suffit de faire  :

$ sudo make install

A ce niveau l’ensemble des fichiers de votre programme ont été installés sur votre machine.

Les répertoires utilisés sont :

/usr/local/bin : répertoire du programme "hello_digitalbox"
/usr/local/include : répertoire des fichiers includes (*.h) 
/usr/local/share/hellodigitalbox/dat : fichiers d'exemple
/usr/local/share/hellodigitalbox/web : fichiers web (php, css, js, ...)
/usr/local/doc/hellodigitalbox : répertoire de documentation

9. Packager

9-package

Vous êtes satisfait de votre script configure ? Faisons un peu de ménage avant de faire le package :

$ make clean
$ rm config.status
$ rm config.log
$ rm Makefile
$ rm src/Makefile
$ rm doc/Makefile
$ rm web/Makefile
$ rm example/Makefile

Et produisez le fichier archive pour le distribuer :

$ cd ..
$ tar -cf HelloDigitalBox.tar HelloDigitalBox
$ gzip HelloDigitalBox.tar

Voilà, votre package peut être diffusé et pourra être compilé/installé sur d’autres machines ! Ce projet assez simple compile aussi sur MacOS par exemple.

Note : si jamais vous vous rendez compte que vous devez faire quelques changements dans les scripts (configure.ac ou bien Makefile.am), alors il faudra rappeler les commandes suivantes :

$ aclocal
$ autoconf
$ automake
$ rm -rf autom4te.cache/

Et retester l’ensemble en rappelant :

$ configure
$ make
$ sudo make install

Voilà, vous savez maintenant comment utiliser dans les grandes lignes autoconf & automake 🙂 Mais quelle est la dixième étape ?

10. Sabrer !

10-bouteille-champagne

Le champagne pardi ! Oui cette étape est bien méritée non ?

En bonus le fichier archive final avec tous les scripts: HelloDigitalBox.

(1) : A tutorial for porting to autoconf & automake

Publicités

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s