Englober plusieurs projets
Projet englobant
On peut aussi inclure dans un projet d'autres projets avec la commande :
add_subdirectory(source_dir)
Portée des variables
add_subdirectory
crée un nouvelle portée (scope) pour les variables du CMakeLists.txt
du sous-répertoire.
- Les variables du
CMakeLists.txt
parent peuvent être lues. Si une telle variable est modifiée, la modification n'est pas visible par le parent. - Les variables du
CMakeLists.txt
du sous-répertoire sont invisibles par le parent.
Notion de liste dans CMake
Une chaîne de caractères peut être interprétée comme une liste, avec
le caractère ;
comme séparateur.
set(varName value ...)
joint les valeurs avec ;
si bien que le contenu de varName peut être
interprété comme la liste des valeurs en argument de set.
set(myVar a b c) # myVar = "a;b;c"
La commande list permet diverses opérations :
list(<opération> varName ...)
où opération peut être LENGTH, GET, INSERT, APPEND, PREPEND etc.
Contexte de message
Possibilité de définir un contexte pour chaque message en modifiant la
variable normale (pas de cache) CMAKE_MESSAGE_CONTEXT
dans
CMakeLists.txt
. Le contenu de CMAKE_MESSAGE_CONTEXT
est
interprété comme une liste dont les éléments sont affichés, séparés
par des points, avant chaque message. Chaque élément de
CMAKE_MESSAGE_CONTEXT
ne peut contenir que lettres, chiffres et
blanc souligné (_
).
Utilisation habituelle :
- On ajoute à
CMAKE_MESSAGE_CONTEXT
un élément indiquant le projet courant :
list(APPEND CMAKE_MESSAGE_CONTEXT <projet>)
- On place cette commande
list
avant la commandeproject
parce que la commandeproject
déclenche les tests du compilateur (avec des affichages correspondants). - Si le projet est englobé, comme chaque projet ajoute un élément au contexte, on voit dans le contexte la pile d'appels.
- Si le projet est englobé avec
add_subdirectory
, la modification deCMAKE_MESSAGE_CONTEXT
est locale.
Choix par l'utilisateur de l'affichage ou non du contexte :
- avec l'option
--log-context
de cmake, seulement pour cette exécution de cmake (pas de création de variable de cache) - ou en définissant la variable de cache
CMAKE_MESSAGE_CONTEXT_SHOW
. Nota bene : cette variable n'est pas prédéfinie par CMake donc si vous la définissez sur la ligne de commande de cmake, donnez-lui son type, BOOL. Exemple :
-DCMAKE_MESSAGE_CONTEXT_SHOW:BOOL=True
Manipulation 23
- Créer un projet englobant les bibliothèques
NR_util
et Jumble. - Compléter
CMakeLists.txt
dansNR_util
:
target_include_directories(nr_util INTERFACE ${PROJECT_BINARY_DIR})
- Compléter
CMakeLists.txt
à la racine de Jumble, écrire lesCMakeLists.txt
dans les sous-répertoires. - Tester.
Manipulation 24
- Créer un projet englobant les bibliothèques
NR_util
, Jumble,Numer_Rec_95
et Coriolis. - Compléter
CMakeLists.txt
aux racines de Jumble etNumer_Rec_95
. - Écrire
CMakeLists.txt
pour Coriolis. - Tester.
Englober ou non un projet dans un autre
Il est intéressant d'englober un projet dans un autre projet dans certains cas particuliers. Exemples :
-
Compiler d'un seul coup un ensemble de bibliothèques, en changeant de machine, ou en changeant de version de compilateur, ou en changeant d'options de compilation (avec options d'analyse de performance, options de débogage, etc.).
-
Quand on distribue le code d'un programme, offrir à l'utilisateur la possibilité de compiler d'un seul coup le programme et ses dépendances, même si les dépendances sont dans des dépôts indépendants. Cf. plus loin
FetchContent
.
Mais en général, on ne veut pas inclure le projet bibliothèque dans tous les projets qui utilisent cette bibliothèque. Cela signifierait à chaque fois déplacer les sources et recompiler : on perdrait une partie de l'intérêt d'une bibliothèque. On préfère utiliser la bibliothèque déjà compilée.