Modèle de projet C basé sur les autotools

Vincent Bernat

HTML5 Boilerplate est souvent utilisé comme modèle pour mettre en place un projet en HTML. Il est à la fois utile pour les développeurs peu expérimentés et pour ceux plus aguerris car il implémente les bonnes pratiques actuelles et permet d’éviter d’en oublier certaines.

J’ai récemment développé quelques projets en C pour un client. Plutôt que d’utiliser le projet précédent comme base, j’ai pensé qu’il serait utile de construire un modèle qui pourrait être réutilisé par la suite. Ainsi est né bootstrap.c1, un modèle pour de petits projets en C se basant sur les autotools.

Utilisation#

La création d’un nouveau projet s’effectue en suivant trois étapes :

  1. Lancer Cookiecutter, un outil en ligne de commande pour créer des projets à partir de modèles, et répondre aux questions.
  2. Configurer Git.
  3. Compléter la « todo list ».

Cookiecutter#

Cookiecutter est un nouvel outil permettant de créer un projet à partir d’un modèle. Il utilise Jinja2 comme moteur, aussi bien pour le nom des fichiers que pour le contenu. Il est indépendant du langage de programmation utilisé et peut donc être utilisé pour du Python, du HTML, du JavaScript ou… du C !

Cookiecutter est un outil se concentrant sur l’essentiel. Vous pouvez lire l’introduction de Daniel Greenfeld pour en savoir plus. Initier un nouveau projet est enfantin :

$ cookiecutter https://github.com/vincentbernat/bootstrap.c.git
Cloning into 'bootstrap.c'...
remote: Counting objects: 90, done.
remote: Compressing objects: 100% (68/68), done.
remote: Total 90 (delta 48), reused 64 (delta 22)
Unpacking objects: 100% (90/90), done.
Checking connectivity... done

full_name (default is "Vincent Bernat")? Alfred Thirsty
email (default is "bernat@luffy.cx")? alfred@thirsty.eu
repo_name (default is "bootstrap")? secretproject
project_name (default is "bootstrap")? secretproject
project_description (default is "boilerplate for small C programs with autotools")? Super secret project for humans

Cookiecutter pose quelques questions pour instantier le modèle. Le résultat est ensuite disponible dans le répertoire supersecret :

.
├── autogen.sh
├── configure.ac
├── get-version
├── m4
│   ├── ax_cflags_gcc_option.m4
│   └── ax_ld_check_flag.m4
├── Makefile.am
├── README.md
└── src
    ├── log.c
    ├── log.h
    ├── Makefile.am
    ├── secretproject.8
    ├── secretproject.c
    └── secretproject.h

2 directories, 13 files

Étapes suivantes#

Il reste quelques étapes à exécuter manuellement. Il convient tout d’abord d’initialiser Git qui est nécessaire pour exploiter certaines fonctionnalités de ce modèle :

$ git init
Initialized empty Git repository in /home/bernat/tmp/secretproject/.git/
$ git add .
$ git commit -m "Initial import"
[…]

Les étapes suivantes sont ensuite extraites des commentaires contenus dans les fichiers sources :

$ git ls-tree -r --name-only HEAD | \
>   xargs grep -nH "T[O]DO:" | \
>   sed 's/\([^:]*:[^:]*\):\(.*\)T[O]DO:\(.*\)/\3 (\1)/' | \
>   sort -ns | \
>   awk '(last != $1) {print ""} {last=$1 ; print}'

2003 Add the dependencies of your project here. (configure.ac:52)
2003 The use of "Jansson" here is an example, you don't have (configure.ac:53)
2003 to keep it. (configure.ac:54)

2004 Each time you have used `PKG_CHECK_MODULES` macro (src/Makefile.am:12)
2004 in `configure.ac`, you get two variables that (src/Makefile.am:13)
2004 you can substitute like above. (src/Makefile.am:14)

3000 It's time for you program to do something. Add anything (src/secretproject.c:76)
3000 you want here. */ (src/secretproject.c:77)
[…]

Ces étapes peuvent être complétées en quelques minutes.

Qu’obtient-on ?#

Voici les principales fonctionnalités :

  • Un configure.ac et un Makefile.am minimalistes.
  • Le journal des changements généré depuis Git ainsi que la gestion automatique des versions depuis les étiquettes Git2.
  • Un squelette pour la page de manuel.
  • Une infrastructure de journalisation utilisant des fonctions variadiques telles que log_warn() et log_info().
Sortie en couleurs de lldpd
Exemple de sortie en couleurs

À propos de l’utilisation des autotools#

Les autotools sont une suite d’outils formant un moteur de production (build system). On y trouve notamment :

  • autoconf pour construire un script de configuration,
  • automake pour construire des makefiles en utilisant un langage similaire mais de plus haut niveau.

Comprendre le fonctionnement des autotools est souvent une activité peu appréciée. Il est facile de dénicher de très mauvaises documentations en commençant par le mauel officiel qui se concentre sur des cas qui ne seront utiles que si vous voulez porter votre projet sur une obscure version de HP-UX. Pourquoi donc partir sur ce système ?

  1. J’ai investi beaucoup de temps dans sa compréhension. Une fois que ses principes sont assimilés, il couvre la plupart des besoins. Peut-être que CMake est plus adapté mais c’est un autre système à apprendre. De plus, l’utilisation des autotools est si répandue qu’il est nécessaire d’en connaître le fonctionnement.
  2. Il existe beaucoup de macros disponibles pour autoconf. La plupart d’entre elles se trouvent prêtes à l’emploi dans l’archive GNU Autoconf. Leur qualité est souvent bonne. Si vous avez besoin de détecter correctement comment compiler un programme avec GNU Readline ou quelque chose de vaguement compatible, il y a une macro pour ça.

Si vous voulez en apprendre plus sur les autotools, il ne faut pas lire le manuel. Lisez plutôt l’excellent Autotools Mythbuster. Commencez avec un configure.ac minimal et n’ajoutez des macros supplémentaires que pour résoudre un réel problème de compatibilité.


  1. Rétrospectivement, je pense que j’aurais dû nommer ce projet boilerplate.c↩︎

  2. Pour plus d’informations sur ces deux fonctionnalités, jetez un œil sur l’article précédent à propos de lldpd↩︎