TD04 : CMake

Les systèmes de construction logicielle, build systems en anglais, sont des logiciels dont l'objet principal est d'automatiser, directement ou indirectement, le processus de compilation d'un code source afin de faciliter le test et la distribution des produits logiciels.

Le moteur de production CMake, populaire du fait de sa caractéristique multi-plateforme, utilise essentiellement des fichiers de configuration, nommés CMakeLists.txt, pour contrôler le processus de compilation. Toutefois, CMake ne génère pas des exécutables, mais des fichiers de constructions standards en fonction de la plateforme. Par exemple, une même configuration CMake génèrera des fichiers Makefile sous Linux et des fichiers de projet Visual Studio sous Windows.

Un fichier CMakeLists.txt contient une liste d'appels à des commandes CMake. Un appel à une commande suit la syntaxe suivante : <nom_commande>(<arg1> <arg2> ...). À titre d'exemple, la présence de la commande cmake_minimum_required(VERSION 3.3) indique qu'il faut utiliser une version de CMake postérieure à la version 3.3. Référez-vous à la documentation de CMake pour une liste des commandes : Documentation.

Exercice 1 : compiler un projet utilisant CMake

  • Placez-vous dans le répertoire temporaire du système /tmp
  • Puis récupérez ce petit projet tetris sur GitHub en faisant le git clone approprié...
  • Testez la compilation out-of-source (dans un autre répertoire, ce qui est fortement recommandé) :
mkdir build
cd build
cmake ..
make

Nota Bene : Il faut préalablement supprimer le fichier cmake/FindSDL2.cmake qui est périmé.

  • Lancez l'exécutable généré, puis regardez le contenu du fichier CMakeLists.txt.
  • Testez maintenant la compilation in-source dans le répertoire contenant les sources :
rm -rf build
cmake .
make
  • Jetez rapidement un œil sur le Makefile généré, qui ne doit pas être très lisible...

Voici une petite démo de tout ça :

demo

Exercice 2 : mon premier CMakeLists.txt

Récupérez les sources du fichier foobar.zip déjà utilisé dans le TD1 sur Makefile.

  • En vous inspirant des exemples de fichier CMakeLists.txt disponibles dans le cours, écrivez un tel fichier pour ce petit projet.
cmake_minimum_required(VERSION 3.3)
project(foobar C)
  • Ajoutez les lignes nécessaires pour génèrer un exécutable foobar à partir des sources contenu dans cette archive.
set(CMAKE_C_FLAGS "-std=c99 -g -Wall")
add_executable(foobar foobar.c bar.c foo.c)
  • Compilez et testez votre projet.
  • Modifiez la fonction bar(double x) pour qu’elle retourne la racine carré de x. Pour cela, il vous faudra inclure dans bar.c le fichier math.h.
  • Mettre à jour le fichier CMakeLists.txt pour préciser que l'exécutable dépend maintenant la bibliothèque m :
target_link_libraries(foobar m)
  • Maintenant nous allons regrouper les deux fichiers foo.c et bar.c dans une même bibliothèque libfb.a qui sera utilisée par l'exécutable foobar. Modifiez votre fichier CMakeLists.txt en utilisant la commande :
add_library(fb foo.c bar.c)
  • Modifiez le reste du fichier pour que l’exécutable soit généré à partir de foobar.c et de la bibliothèque fb et non directement à partir des sources foo.c et bar.c.
  • Vérifiez que tout compile correctement.

Nota Bene : Avec CMake, il n'est pas obligatoire de spécifier les dépendances sur les fichiers header d'extension .h, qui sont résolus automatiquement :-)

Exercice 3 : compilation de TSP avec CMake

Le fichier tsp.zip (déjà étudié dans le TD1) contient les sources permettant de générer 2 exécutables :

  • solve qui résout le problème du voyageur de commerce (dont les instances sont codées dans des fichiers .TSP)
  • convert qui permet de convertir des fichiers d'un format à un autre.

Ces deux exécutables utilisent les modules matrice2d, tsp et memoire ainsi que la bibliothèque mathématique libm.a.

  • En repartant de votre fichier Makefile produit lors du TD1, écrivez un fichier CMakeLists.txt permettant de générer ces exécutables. (Il n'est pas nécessaire de créer une bibliothèque intermédiaire.)
  • Rendez finalement votre fichier CMakeLists.txt sous Moodle et faites Run pour le tester...

Exercice 4 : passage de Game Text sous CMake

Dans cet exercice, il vous est demandé maintenant de travailler en équipe.

  • Commencez par sélectionner la meilleure version de votre projet pour la suite de votre projet en équipe...
  • Puis intégrez tous les fichiers sources nécessaires à la compilation de votre projet à la racine de votre dépôt Git.
  • Hormis le fichier libgame.a, votre dépôt ne doit comporter que des fichiers sources (ou textes) et il ne doit comporter aucun fichiers temporaires ou générés.
  • Remplacez maintenant votre fichier Makefile par un fichier CMakeLists.txt pour compiler votre projet et générer l'exécutable game_text.
  • Ajoutez dans votre CMakeLists.txt la commande link_directories(${CMAKE_SOURCE_DIR}) pour indiquer où se trouver la bibliothèque libgame.a. Cette commande ne sera plus nécessaire quand vous implémenterez (TD06) les fichiers game.c et game_aux.c.
  • Récupérez tous la dernière version de votre projet et vérifiez que la compilation avec CMake se passe bien. Sinon corrigez le problème.
  • Vous êtes maintenant collectivement responsable du bon fonctionnement de votre projet et vous ne devez en aucun cas soumettre des modifications qui ne compilent pas, au risque de compromettre le travail de votre équipe !
  • Une fois que vous avez finalisé ce travail, un membre de l'équipe (et un seul) doit soumettre dans le fichier rendu.txt sous Moodle votre REPOSITORY et le COMMIT approprié, selon le format strict introduit au TD3.
  • N'oubliez pas de faire run dans l'activité VPL de Moodle pour vérifier que votre rendu est acceptable, sinon vous risquez la note de 0/100 !

Important : Concernant l'organisation de votre projet Git, il est important que le fichier README.md et CMakeLists.txt se trouve à la racine de votre projet. De plus, pour le bon fonctionnement des corrections automatiques avec VPL, il est nécessaire que les fichiers produits comme game_text soient tous à plat dans le répertoire de build.