Blog ENI : Toute la veille numérique !
💥 Un livre PAPIER acheté
= La version EN LIGNE offerte pendant 1 an !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici

Automatisation de la compilation

Introduction

Ce chapitre pose les bases pour utiliser les outils autoconf, automake et libtool. Nous avons vu que pour de petits et moyens projets nous pouvions utiliser l’outil make dans la recette "Automatiser la compilation avec make" (chapitre "Outils de compilation"). Cependant, dès lors que vous voulez automatiser la compilation tout en proposant des outils assez simples à l’utilisateur pour modifier quelques paramètres de compilation, ou capables de tenir compte des versions des composants logiciels pré-requis, make ne suffit plus. Plusieurs projets furent lancés dans ce but, et nous pouvons citer xmkmf, aujourd’hui tombé dans l’oubli car il nécessitait un serveur X11 dont il faisait partie de la suite logicielle. Son concurrent, l’ensemble autoconf, automake et libtool lui a survécu et est devenu un standard pour les développeurs de logiciels libres.

Les versions de ces logiciels sont assez compatibles entre elles à partir de la 2.50 pour autoconf, 1.6 pour automake et 1.4 pour libtool. Par conséquent, en fonction de la machine dont vous disposez, vous n’aurez pas forcément la version la plus récente de ces logiciels, mais cela n’est pas génant pour la lecture de ce chapitre. Les exemples ont été écrits avec les versions 2.59 d’autoconf, 1.8.5 d’automake et 1.5.14...

Démarrer un projet avec autoconf et automake

Problème

Vous disposez des sources d’un programme et vous souhaitez ajouter ou remplacer les scripts de compilation par ceux générés par autoconf et automake.

Solution

L’automatisation de la compilation avec autoconf et automake suit les étapes suivantes :

 Mettre les sources dans src/.

 Exécuter autoscan.

 Créer configure.ac à partir de configure.scan ainsi généré.

 Éditer Makefile.am et src/Makefile.am.

 Ajouter les fichiers manquants (AUTHORS, NEWS...).

 Exécuter aclocal, autoconf, autoheader, automake.

 Tester l’ensemble.

 make distcheck.

 Tester à partir du résultat.

Discussion

Étape 1. La première étape consiste à créer un répertoire, initialement vide, que nous appelons racine, et un sous-répertoire généralement nommé src/. Déplacez les fichiers source (sans les scripts de compilation) dans ce répertoire src/. Pour l’exemple, nous supposerons que nos sources consistent en trois fichiers main.c, util.c et util.h.

Étape 2. Afin de créer un script nécessaire à autoconf, exécutez autoscan sans arguments. Un fichier configure.scan est ainsi créé.

Étape 3. Vous pouvez renommer ce fichier configure.scan en configure.ac...

Ajouter des tests de fonctions ou de bibliothèques

Problème

Lors de l’exécution du script configure, vous voulez tester si une fonction ou une bibliothèque est présente sur le système, puis modifier les options du compilateur et de l’éditeur de liens en fonction de l’emplacement de la bibliothèque concernée.

Solution

Ajoutez le nom de la fonction à tester à la macro AC_CHECK_FUNCS et le nom d’un fichier d’en-têtes à la macro AC_CHECK_HEADERS. Indiquez le nom d’une bibliothèque à AC_CHECK_LIB.

Discussion

Nous distinguons plusieurs cas et proposerons à chaque fois un extrait du script configure.ac.

Fonction de libc

Pour tester si une fonction se trouve dans la bibliothèque C standard, lisez la page de manuel correspondante et effectuez un test sur les fichiers d’en-têtes correspondants, puis sur la fonction elle-même. Voici un exemple pour pthread_create() :


AC_CHECK_HEADERS(pthread.h, [], [exit]) 
AC_CHECK_FUNC(pthread_create, [], [exit])
 

Le premier argument est, première ligne, l’en-tête à vérifier et, ligne suivante, la fonction dont la présence en standard est vérifiée. Le deuxième argument est l’instruction à exécuter si le test est concluant, donc ici, rien, puisqu’il n’y a rien à faire. Le troisième argument est l’instruction à exécuter si le test échoue. Ici, nous choisissons de nous arrêter avec exit.

Fonction d’une bibliothèque quelconque

Pour tester la présence d’une bibliothèque quelconque, et dans le cas favorable, ajuster les options de compilation et d’édition des liens...

Récupérer les variables de la commande ./configure

Problème

Vous souhaitez personnaliser la ligne de commande afin de paramétrer les options du compilateur ou de spécifier des macros à utiliser via la compilation conditionnelle.

Solution

Utilisez AC_ARG_WITH pour obtenir les options de type --with-[...] et AC_ARG_ENABLE pour celles de type --enable-[...].

Discussion

Lorsque vous exécutez le script configure, vous pouvez lui fournir plusieurs types d’arguments. Certains permettent de changer certaines variables. C’est le cas de l’option la plus connue --prefix qui change le contenu de la variable prefix. La liste de ces options est accessible avec configure  --help.

D’autres options du type --with-option sont directement programmables avec AC_ARG_WITH. Le premier argument est l’option. Le second est un message d’aide, qui est affiché lorsque l’utilisateur exécute configure --help. Les deux derniers arguments sont les actions, si l’option est indiquée sur la ligne de commande et si elle ne l’est pas. Dans le premier cas, la variable withval contient ce que l’utilisateur a éventuellement spécifié après le signe = facultatif. Deux exemples dans la recette précédente illustrent l’utilisation de AC_ARG_WITH dans des conditions concrètes. L’exemple suivant montre d’autres possibilités :...

Passer des options supplémentaires au compilateur

Problème

Vous souhaitez ajouter des options supplémentaires au compilateur ou à l’éditeur de liens.

Solution

Utilisez les variables CFLAGS et LDFLAGS, et leurs dérivées.

Discussion

Dans la recette précédente nous avons vu que nous pouvions définir des variables avec AC_SUBST que vous retrouvez dans le fichier Makefile.am. Nous pouvons les utiliser pour ajouter des options de compilation ou d’édition des liens avec les variables de suffixe _CFLAGS et _LDADD. L’exemple suivant ajoute les options -Wall -O2 au compilateur dans le fichier Makefile.am :

exemple_CFLAGS=-Wall -O2
 

Vous pouvez aussi utiliser les variables CFLAGS et LDFLAGS qui sont prises en compte systématiquement par le compilateur et l’éditeur de liens. En indiquant CFLAGS=-Wall, tous les programmes compilés le seront avec cette option. Pour avoir un binaire statique, utilisez LDFLAGS=-static.

Vous pouvez définir ces variables de manière définitive dans le fichier configure.ac comme cela est conseillé pour l’option -Wall :


changequote(,) 
if test "x$GCC" = "xyes"; then 
  case " $CFLAGS " in 
  *[\ \ ]-Wall[\ \      ]*) ;; 
  *) CFLAGS="$CFLAGS -Wall" ;; 
  esac 
fi 
changequote([,])
 

Attention ! La quatrième ligne contient une tabulation avant le dernier crochet fermant...

Prendre en compte l’internationalisation d’un projet

Problème

Vous avez internationalisé votre projet avec gettext (chapitre "Internationalisation") et souhaitez intégrer l’automatisation de la gestion des langues dans le projet avec autoconf et automake.

Solution

Exécutez gettextize -c et effectuez les modifications nécessaires dans les différents fichiers configure.ac, Makefile.am, src/Makefile.am et po/POTFILES.in.

Discussion

Pour automatiser l’internationalisation, certains fichiers manquants sont créés en exécutant gettextize -c dans le répertoire qui contient configure.ac. Cela ajoute des répertoires, dont po/. Certaines versions de gettextize modifient elles-mêmes certains fichiers, puis affichent un texte indiquant la suite des opérations. Lorsque ce texte est affiché, suivez-le en parallèle avec cette recette.

Éditez le fichier Makefile.am afin d’ajouter les répertoires ainsi créés :


SUBDIRS=intl src po
 

Certaines versions de gettextize créent un répertoire m4/ dont il faut rajouter le nom à la liste. Certaines ne créent pas le répertoire intl/ que vous n’ajouterez pas dans ce cas.

Éditez aussi configure.ac afin d’y mettre la liste des langues supportées et un appel à la macro AM_GNU_GETTEXT :


ALL_LINGUAS="fr" ...

Utiliser autoconf, automake et libtool pour créer une bibliothèque

Problème

Vous souhaitez tirer profit de l’automatisation de la création des scripts de compilation et en particulier libtool afin de créer une bibliothèque.

Solution

Exécutez libtoolize -c et adaptez les fichiers configure.ac et Makefile.am pour prendre en compte l’utilisation de libtool.

Discussion

Pour adapter les scripts configure.ac et Makefile.am, nous commençons par exécuter libtoolize -c qui copie certains fichiers dont libtool dans le répertoire source racine du projet. Puis nous pouvons éditer configure.ac. Nous y ajoutons les lignes suivantes :


LIBTEST_CURRENT=0 
LIBTEST_REVISION=0 
LIBTEST_AGE=0 
AC_SUBST(LIBTEST_CURRENT) 
AC_SUBST(LIBTEST_REVISION) 
AC_SUBST(LIBTEST_AGE) 
 
AM_PROG_LIBTOOL
 

La dernière ligne indique aux différents utilitaires que nous utilisons libtool. Les autres permettent de centraliser la définition du numéro de version de la bibliothèque, sachant que le principe de numérotation peut varier d’un système à l’autre. Libtool nous propose donc ainsi un système uniforme et s’adapte ensuite au système sur lequel il est exécuté.

Libtool part du principe qu’un numéro de version est codé actuel:révision:ancienneté. Le numéro...

Créer une bibliothèque et l’utiliser dans un projet avec autoconf et automake

Problème

Votre projet contient une bibliothèque dans un répertoire et vous souhaiteriez l’utiliser dans un programme dont le code source se trouve dans un autre répertoire.

Solution

Programmez vos scripts de manière à compiler la bibliothèque en premier, puis indiquez les bons chemins pour les fichiers d’en-têtes à la compilation du programme et pour la bibliothèque lors de l’édition des liens.

Discussion

L’ordre de compilation des composants d’un projet correspond à l’ordre des répertoires listés dans la variable SUBDIRS dans le fichier Makefile.am du répertoire racine des sources. Pour un projet contenant une bibliothèque dans le répertoire libtest/ et un programme dans le répertoire src/, la bibliothèque sera compilée avant le programme avec un fichier Makefile.am contenant ceci :


SUBDIRS=libtest src 

Dans le fichier Makefile.am dans le répertoire du programme, vous souhaitez indiquer au compilateur (option -I) et à l’éditeur de liens (option -L) le chemin de la bibliothèque. Ces chemins ne peuvent pas être relatifs au répertoire courant car dans certaines conditions (lors de l’exécution de make distcheck par exemple), l’emplacement...