Premiers pas avec CMake
Installation de CMake
Avec le gestionnaire de paquets de votre distribution Linux. Sur Ubuntu :
apt install cmake cmake-curses-gui cmake-qt-gui
Si la version fournie par votre distribution est trop vieille, il est facile aussi d'installer la dernière version sur le site de CMake, au format binaire.
Principe
CMake met en œuvre l'idée de configuration. On écrit les informations
décrivant le code (liste des fichiers, noms des bibliothèques
nécessaires (sans les chemins) etc.) dans un fichier appelé
CMakeLists.txt
. On n'indique pas le compilateur, les options de
compilation, le chemin des bibliothèques dans CMakeLists.txt
. Ces
choix seront faits au moment de la configuration.
CMake gère la configuration et nécessite un autre outil pour la compilation. CMake peut travailler avec plusieurs outils de compilation au choix de l'utilisateur, et selon le système d'exploitation de la machine de compilation (on dit encore : selon la "plateforme"). CMake appelle ces outils des générateurs. Pour voir la liste disponible sur sa machine :
cmake --help
Sur Linux, les générateurs sont make et Ninja. Avec make, par exemple, CMake va créer des makefiles (très compliqués).
Répertoire de compilation
- CMake crée des fichiers pour le générateur (des makefiles si le générateur est make, par exemple) dans un répertoire quelconque, choisi par l'utilisateur.
- Le générateur (make par exemple) est invoqué depuis ce répertoire et les produits de compilation sont créés dans ce répertoire.
- Répertoire de compilation = build dir = binary dir
La question du suffixe à nouveau
CMake a la même convention que la plupart des compilateurs : il
suppose par défaut que .f90
et .F90
indiquent le format libre,
.f
et .F
le format fixe. Il n'y a donc plus de raison (qu'il y
avait pour make) de faire un autre choix.
Langage de CMake
(Le point noir de CMake)
- Un fichier
CMakeLists.txt
est écrit dans un langage spécifique à CMake. - Des variables, des structures de contrôle (alternative, itération), des commandes, des fonctions…
-
Les noms de commandes, de fonctions sont insensibles à la casse. Les noms de variables sont sensibles à la casse.
-
Commentaires :
#
- Valeur d'une variable :
${myVar}
- Les arguments d'une commande ou d'une fonction sont entre parenthèses séparés par des espaces ou des retours à la ligne.
Manipulation 13 : programme trivial
Écrivez le fichier CMakeLists.txt
:
cmake_minimum_required(VERSION 3.16)
project(Plouf LANGUAGES Fortran)
add_executable(plouf plouf.f90)
Dans la commande cmake_minimum_required
, vous pouvez choisir un
numéro de version de CMake autre que 3.16
. Conseil : dans le doute,
mettez le numéro de votre version. Ce qui entre en ligne de compte
dans le choix : partage du code, version disponible dans les
distributions Linux, fonctionnalités de CMake utilisées.
Dans la commande project
, le premier arugment est le nom du
projet. Vous pouvez choisir ce que vous voulez (vous n'êtes pas obligé
de prendre le même nom que celui de l'exécutable, mais c'est une bonne
idée).
Dans la commande add_executable
, le premier argument est un nom de
"cible". C'est un identificateur dans CMake. Le nom du fichier
exécutable est créé à partir du nom de la cible, selon la convention
du système d'exploitation. Ne pas mettre de suffixe. Vous pouvez
choisir ce que vous voulez mais c'est une bonne idée de prendre le nom
du fichier source Fortran sans suffixe.
Attention : la casse n'importe pas pour les noms des commandes mais elle importe pour tous les autres mots.
Créez un répertoire de compilation :
mkdir build
cd build
Vous pouvez choisir un nom quelconque autre que build
. Vous pouvez
choisir ce répertoire n'importe où, en particulier en dehors de
l'arborescence des sources. Vous pourriez même ne pas créer de
répertoire de compilation et rester dans le répertoire source mais
cela est déconseillé : CMake va créer beaucoup de fichiers pour le
générateur, en plus des produits de la compilation. Par exemple si le
générateur est make, CMake va créer beaucoup plus qu'un makefile.
Lancez la configuration :
cmake ..
L'argument de cmake doit être le chemin vers la racine de
l'arborescence source, contenant CMakeLists.txt
. Donc ce peut être
le répertoire parent, ..
ou sinon ce peut être n'importe quel chemin
(relatif ou absolu).
Lancez la compilation :
make
Essayez make
une seconde fois.
Manipulation 14 : arguments possibles de make
Les cibles de make :
make help
Voir les commandes invoquées par make :
make VERBOSE=1
Manipulation 15 : cmake-gui
Alternative à la commande cmake
dans le terminal, pour choisir
interactivement la configuration avec une interface graphique.
cd build
rm -r *
cmake-gui ..
L'argument de cmake-gui doit être le chemin vers la racine de l'arborescence source. Cliquer sur "Configure". Choix :
- du générateur
- du compilateur
- du type de compilation : débogage, rapidité (Release), etc.
Cliquer sur "Generate".
make
Configuration et génération
Le travail de CMake est en fait divisé en deux étapes :
- Configuration : CMake se construit une représentation interne du projet, indépendante du générateur choisi.
- Génération : CMake crée les fichiers pour le générateur choisi.
Vocabulaire source de confusion : la génération est une opération faite par CMake et non par le générateur.
cmake
sur la ligne de commande : configuration et génération
enchaînées automatiquement. cmake-gui
: deux boutons.
Manipulation 16 : équivalence de cmake et cmake-gui
Tous les choix avec cmake-gui peuvent aussi être faits avec cmake sur la ligne de commande. Par exemple :
cd build
rm -r *
cmake -DCMAKE_BUILD_TYPE=Debug ..
make VERBOSE=1
Manipulation 17 : voir la configuration après coup
Après cmake ou cmake-gui, pour voir la configuration qui a été
choisie, regarder le fichier CMakeCache.txt
créé dans le répertoire
de compilation. Notamment : CMAKE_BUILD_TYPE
,
CMAKE_Fortran_COMPILER
Pour voir les options de compilation et la commande d'édition de liens qui vont être utilisées par make :
CMakeFiles/plouf.dir/flags.make
CMakeFiles/plouf.dir/link.txt
Le répertoire contenant flags.make
et link.txt
est nommé à partir
du nom de la cible.
Modifier la configuration
On peut relancer cmake ou cmake-gui.
Une fois que le fichier CMakeCache.txt
existe, il n'est plus
nécessaire de répéter sur la ligne de commande le chemin des sources :
cmake .
ou
cmake-gui .
suffit.
Avec cmake, il n'est plus nécessaire non plus de répéter les options
-D
. On peut en modifier une partie ou en mettre de nouvelles.
Pour voir simplement les options :
cmake -L -N .
Si on modifie le fichier CMakeLists.txt
, il n'est même pas
nécessaire de relancer cmake
. On peut directement lancer make
. La
modification de CMakeLists.txt
est détectée et la configuration est
enchaînée automatiquement avec la compilation.
Manipulation 18 : plusieurs configurations
cd ..
mkdir build_release
cd build_release
cmake -DCMAKE_BUILD_TYPE=Release ..
make VERBOSE=1
Un système prometteur
Le système de CMake : créer des fichiers de générateur (des makefiles) dans un répertoire indépendant des sources, répond à nos attentes :
-
Placer les produits de compilation dans un répertoire indépendant des sources.
-
Basculer facilement entre des options de débogage et des options de rapidité, ou changer de compilateur : il suffit de créer des répertoires pour différentes configurations. Pas de recompilation inutile lorsqu'on passe de l'un à l'autre. Aucune autre opération à faire que changer de répertoire.
-
Changer de machine. On peut laisser sur une machine le répertoire de compilation et déplacer les sources sur une autre machine. Si on revient à une machine, pourvu que l'on rapporte les sources au même endroit, la configuration de compilation est prête : rien à refaire.
- Partage du code : on partage
CMakeLists.txt
, indépendant du compilateur et de la machine.