Autotools en C/Version imprimable

Ceci est la version imprimable de Autotools en C.
  • Si vous imprimez cette page, choisissez « Aperçu avant impression » dans votre navigateur, ou cliquez sur le lien Version imprimable dans la boîte à outils, vous verrez cette page sans ce message, ni éléments de navigation sur la gauche ou en haut.
  • Cliquez sur Rafraîchir cette page pour obtenir la dernière version du wikilivre.
  • Pour plus d'informations sur les version imprimables, y compris la manière d'obtenir une version PDF, vous pouvez lire l'article Versions imprimables.


Autotools en C

Une version à jour et éditable de ce livre est disponible sur Wikilivres,
une bibliothèque de livres pédagogiques, à l'URL :
https://fr.wikibooks.org/wiki/Autotools_en_C

Vous avez la permission de copier, distribuer et/ou modifier ce document selon les termes de la Licence de documentation libre GNU, version 1.2 ou plus récente publiée par la Free Software Foundation ; sans sections inaltérables, sans texte de première page de couverture et sans Texte de dernière page de couverture. Une copie de cette licence est incluse dans l'annexe nommée « Licence de documentation libre GNU ».

Présentation

Les Autotools sont des logiciels libres développés par la Free Software Foundation. Ils sont utilisés pour automatiser la compilation. Les développeurs qui maintiennent :

  • Paul Eggert
  • Eric Blake <ebb9@byu.net>

Les Autotools sont pour la plupart écrits en Perl.


Introduction

 
Organigramme

Introduction

modifier

Il s'agit ici de montrer le fonctionnement de base des Autotools :

  • aclocal
  • autoscan
  • autoheader
  • autoconf
  • automake
  • autogen

Les autotools permettent à un programme de gérer les dépendances requises par un programme ainsi que les options de compilation pour des machines différentes.

Seront vus ici ces aspects :

  • mise en place d'un programme en c
  • rédaction des fichiers de configuration configure.ac et Makefile.am
  • internationalisation
  • tests logiciel
  • compilation croisée
  • documentation (gtk-doc, Doxygen, pages de manuel)
  • profilage
  • git

Ces outils permettent de compiler dans un grand nombre de langages, C++, python, etc. et même LaTeX.


Programme exemple

Nous verrons ici les utilisations les plus simples (par ex : ajouter un fichier), qui sont aussi les plus quotidiennes pour un développeur.

Préparations du programme Affichage

modifier

Nous allons créer un programme Affichage qui produira un simple "Bonjour" dans le terminal. Par respect pour les autres développeurs, nous suivons ici les standards de programmation (notamment GNU). Il est en effet habituel de mettre son code dans un répertoire du même nom que le programme. À l'intérieur de ce répertoire nous placerons le code source dans src/ (ultérieurement, nous créerons docs/ pour la documentation, tests/, po/ pour l'internationalisation du programme, etc.)

Notre arborescence pour l'instant :

affichage/
  src/

On crée le fichier source en langage C dans src/ :

affichage/
  src/
   programme.c

Et éditons-le pour y placer notre code trivial :

/* programme.c */
void main()
{
  printf("Bonjour\n");
}

Fichiers de configuration

modifier

Pour fonctionner, Autotools se sert de plusieurs fichiers qu'il va créer mais requiert trois fichiers de notre part dont deux sont plus importants  :

  • configure.ac servant à configurer autoconf
  • Makefile.am qui sera utilisé par automake
  • README

configure.ac

modifier

Pour faciliter la rédaction de ce fichier, utilisons le programme autoscan qui va fournir un modèle. Pour cela, il faut se placer dans le répertoire principal affichage :

$ cd affichage/
$ autoscan

autoscan va générer un fichier configure.scan. Son édition va nous permettre de compléter quelques champs :

AC_PREREQ([2.65])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_CONFIG_SRCDIR([src/programme.c])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_OUTPUT

Il sera modifié et complété :

AC_PREREQ([2.65])
AC_INIT(affichage, 0.01, affichage@gnu.org) # remplir ici le nom du programme, version, courriel du développeur
AC_CONFIG_SRCDIR([src/programme.c])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_OUTPUT
(
Makefile     # on reconstitue ici l'arborescence qui doit
src/Makefile # être parcourue
)

Une fois édité, on le renomme en configure.ac. Donc à ce stade, l'arborescence doit être :

affichage/
  configure.ac
  src/
   programme.c

Makefile.am

modifier

Il y aura plusieurs fichiers de ce type : autant de Makefile.am que de répertoire à parcourir, un dans le répertoire principal affichage/ et un dans src/. Dans la plupart des projets, il ne contient qu'une ou deux lignes : la liste des sous-répertoires qu'il faudra parcourir dans notre exemple le répertoire src. Pour l'indiquer à Automake, il faut renseigner la variable «SRC» dont c'est justement le rôle.

On ajoute un Makefile.am :

affichage/
  configure.ac
  Makefile.am
  src/
   programme.c

Dans lequel on place ce contenu :

SUBDIRS=src

Et on en crée un deuxième :

affichage/
  configure.ac
  Makefile.am
  src/
   Makefile.am
   programme.c

Dans lequel on va écrire :

bin_PROGRAMS=affichage
affichage_SOURCES=programme.c

Sa rédaction ne pose aucun problème car son contenu n'est pas lu par Automake. Seule sa présence est requise. Il est cependant toujours conseillé de renseigner ces fichiers :

  • la documentation augmente la qualité du logiciel
  • l'utilisateur est toujours heureux de pouvoir trouver une aide en cas de problème

Toujours pour des raisons de cohérences entre les programmes, il est conseillé d'autre part de s'inspirer d'un README existant pour respecter ses conventions typographiques et se laisser guider par les infos qu'il est bon ou pas de placer dans ce fichier.

autogen.sh

modifier

Ce script (disponible ici) va nous permettre de simplifier la construction, car il réalise toutes les opérations nécessaires de manière automatique. Même si tout est automatique, il faut quand même savoir que ce script lance plusieurs commandes différentes dont :

$ aclocal
$ autoconf
$ autoheader
$ automake

Il faut noter qu'après ce lancement certains fichiers seront créés dont INSTALL, AUTHORS (vide : à compléter), ChangeLog (vide aussi), NOTES (vide), TODO (vide). Encore une fois, maintenir ces fichiers n'est pas difficile et toujours profitable aux utilisateurs.

affichage/
  autogen.sh
  configure.ac
  Makefile.am
  README
  src/
   Makefile.am
   programme.c

Maintenant que tout est prêt, lançons le script :

$ ./autogen.sh

LICENSE

modifier

Enfin, il faut penser aussi utiliser la bonne licence légale à ajouter au logiciel. Par défaut, GNU Gpl. Nous la garderons, mais il faut faire une petite modification : ajouter le nom du programme et la date.


Premiers pas

Construction des fichiers intermédiaires

modifier

La seule difficulté était de rédiger correctement les deux fichiers configure.ac et Makefile.am. Une fois cette étape passée, une suite de commande est à lancer pour construire les fichiers nécessaires

  1. aclocal
  2. autoheader
  3. autoconf
  4. automake -a -c

Construction utilisateur

modifier

Jusqu'ici, il s'agissait d'actions faites par le développeur du programme. L'utilisateur, pour sa part, doit juste avoir à lancer les commandes communément utilisées : ./configure et make (voire make install). Les actions menées ont permis d'aboutir au Makefile qui permet de lancer la commande make.

$ ./configure
$ make

On aboutit ici à la production du fichier binaire, compilé avec GCC par défaut sous les systèmes GNU/Linux.


Ajout d'une fonction

Nous partons du projet précédent. Voici une opération très courante lorsqu'on programme avec ces outils. Ajouter un fichier va vouloir dire : modifier le Makefile.am et créer les fichiers dans src/

Ajout d'une fonction

modifier

Ce titre signifie en fait, une fonction contenue dans un autre fichier que programme.c; par conséquent, notre projet s'enrichit d'un fichier...

/* fonction_affichage.c */
#include <stdio.h>

int affichage(char *phrase)
{
  fprintf(stdin, "%s", phrase);
  return 0;
}

... ou plutôt de deux. Il faut prendre l'habitude d'avoir les en-têtes dans un fichier séparé. Cela sera utile pour les tests par exemple et d'une manière générale c'est plus propre pour la réutilisation des fonctions.

/* entête fonction_affichage.h */
int affichage(char *phrase);

D'ailleurs pour être encore plus propre nous allons mettre ce qu'il faut pour empêcher les inclusions multiples.

/* entête fonction_affichage.h */
#ifndef FONCTION_AFFICHAGE_H
#define FONCTION_AFFICHAGE_H
int affichage(char *phrase);
#endif

Et le fichier principal modifié :

/* programme.c */
#include "fonction_affichage.h"

int main()
{
  affichage("Bonjour\n");
  return 0;
}

En résumé, nous avons deux nouveaux fichiers : fonction_affichage.c, fonction_affichage.h. En plus, nous avons modifié programme.c. Nous avons donc l'arborescence suivante :

affichage/
  src/
   programme.c
   fonction_affichage.c
   fonction_affichage.h

Il faut en informer le Makefile.am contenu dans src/

bin_PROGRAMS=affichage
affichage_SOURCE=programme.c fonction_affichage.c fonction_affichage.h

On peut relancer la compilation qui va mettre ces fichiers à jour :

$ make

Il est courant d'oublier une étape voici un résumé quand on veut ajouter un fichier :

  1. créer le fichier.c
  2. créer le fichier.h
  3. ajouter ces fichiers dans le Makefile.am
  4. ajouter "fichier.h" au dessus de la fonction main dans le fichier principal du programme
  GFDL Vous avez la permission de copier, distribuer et/ou modifier ce document selon les termes de la licence de documentation libre GNU, version 1.2 ou plus récente publiée par la Free Software Foundation ; sans sections inaltérables, sans texte de première page de couverture et sans texte de dernière page de couverture.