web-dev-qa-db-fra.com

Comment fonctionne exactement CMake?

Je ne demande pas cela juste pour moi. J'espère que cette question sera une référence pour les nombreux débutants qui, comme moi, l'ont trouvée complètement perplexe sur ce qui se passait dans les coulisses quand, pour un si petit CMakeLists.txt fichier

cmake_minimum_required (VERSION 2.6)
project(Tutorial)
add_executable(Tutorial tutorial.cpp)

et un si petit tutorial.cpp

int main() { return 0; } 

il y a tellement de fichiers générés

CMakeCache.txt  cmake_install.cmake  Makefile
CMakeLists.txt  tutorial.cpp

et un dossier CMakeFiles avec autant de fichiers et de dossiers

CMakeCCompiler.cmake               CMakeOutput.log    Makefile.cmake
cmake.check_cache                  CMakeSystem.cmake  progress.marks
CMakeCXXCompiler.cmake             CMakeTmp           TargetDirectories.txt
CMakeDetermineCompilerABI_C.bin    CompilerIdC        Tutorial.dir
CMakeDetermineCompilerABI_CXX.bin  CompilerIdCXX
CMakeDirectoryInformation.cmake    Makefile2

Ne pas comprendre ce qui se passait dans les coulisses (c.-à-d. Pourquoi des fichiers devaient être générés et quelle était leur fonction) était le principal obstacle à l’apprentissage de CMake.

Si quelqu'un le sait, pourriez-vous s'il vous plaît l'expliquer pour la postérité? Quel est le but de ces fichiers et quand je tape cmake ., qu'est-ce que cmake configure et génère exactement avant de construire le projet?

134
Nav

Le secret est que vous n'avez pas à comprendre ce que font les fichiers générés.

CMake introduit beaucoup de complexité dans le système de construction, dont la plupart ne rapporte que si vous l'utilisez pour construire des projets logiciels complexes.

La bonne nouvelle est que CMake s’efforce de vous garder une bonne part de ce désordre: utilisez versions hors-source et vous n’aurez même pas à consulter les fichiers générés. Si vous ne l’avez pas fait jusqu’à présent (ce qui, je suppose, est le cas, puisque vous avez écrit cmake .), veuillez les vérifier avant de continuer. Mélanger le répertoire de compilation et le répertoire source est très pénible avec CMake et ce n’est pas la façon dont le système est censé être utilisé.

En un mot: au lieu de

cd <source_dir>
cmake .

toujours utiliser

cd <build_dir_different_from_source_dir>
cmake <source_dir>

au lieu. J'utilise généralement un sous-dossier vide build dans mon répertoire source en tant que répertoire de construction.

Pour soulager votre douleur, laissez-moi vous donner un aperçu rapide des fichiers pertinents générés par CMake:

  • Fichiers du projet/Makefiles - Ce qui vous intéresse réellement: Les fichiers nécessaires à la construction de votre projet sous le générateur sélectionné. Cela peut être quelque chose d'un Makefile Unix à une solution Visual Studio.
  • CMakeCache.txt - Il s'agit d'un stockage de chaîne clé/valeur persistant utilisé pour mettre en cache la valeur entre les exécutions. Les valeurs stockées ici peuvent être des chemins vers des dépendances de bibliothèque ou si un composant facultatif doit être construit. La liste de variables est pratiquement identique à celle que vous voyez lorsque vous exécutez ccmake ou cmake-gui. Cela peut être utile de regarder de temps en temps, mais je recommanderais d'utiliser les outils susmentionnés pour changer les valeurs si possible.
  • Fichiers générés - Cela peut être des fichiers source générés automatiquement aux macros d'exportation qui vous aident à réintégrer votre projet construit à d'autres projets CMake. La plupart d'entre eux sont uniquement générés à la demande et n'apparaîtront pas dans un projet aussi simple que celui de votre question.
  • Tout ce qui reste est un peu comme du bruit pour garder le système de construction heureux. En particulier, je n'ai jamais eu à me soucier de quoi que ce soit qui se passe dans le sous-répertoire CMakeFiles.

En général, vous ne devriez pas jouer avec les fichiers que CMake génère pour vous. Tous les problèmes peuvent être résolus de l'intérieur CMakeLists.txt d'une manière ou d'une autre. Tant que le résultat construit votre projet comme prévu, vous allez probablement bien. Ne vous inquiétez pas trop des détails sanglants - c’est ce que CMake essayait de vous épargner en premier lieu.

79
ComicSansMS

Comme indiqué sur son site web:

Cmake est un système de construction multi-plateformes et à code source ouvert permettant de gérer le processus de construction d'un logiciel à l'aide d'une méthode indépendante du compilateur.

Dans la plupart des cas, il est utilisé pour générer des fichiers de projet/création. Dans votre exemple, il a généré Makefile qui sont utilisés pour construire votre logiciel (principalement sur la plate-forme Linux/Unix).

Cmake permet de fournir des fichiers de construction inter-plateformes générant des fichiers de projet/création spécifiques à une plate-forme pour une compilation/plate-forme particulière.

Par exemple, vous pouvez essayer de compiler votre logiciel sous Windows avec Visual Studio, puis avec la syntaxe appropriée dans votre CMakeLists.txt fichier que vous pouvez lancer

cmake .

dans le répertoire de votre projet sur la plate-forme Windows, Cmake générera tous les fichiers de projet/solution nécessaires (.sln etc.).

Si vous souhaitez créer votre logiciel sur la plate-forme Linux/Unix, vous devez simplement aller dans le répertoire source où vous avez votre CMakeLists.txt file et déclenche le même cmake . et il générera tous les fichiers nécessaires à la construction du logiciel via le simple make ou make all.

Vous avez ici une très bonne présentation des fonctionnalités clés de Cmake http://www.elpauer.org/stuff/learning_cmake.pdf

[~ # ~] éditer [~ # ~]

Si vous souhaitez que la bibliothèque dépende de la plate-forme inclue/définitions de variable, etc., vous pouvez utiliser cette syntaxe dans CMakeLists.txt fichier

IF(WIN32)
   ...do something...
 ELSE(WIN32)
   ...do something else...
 ENDIF(WIN32)

Il existe également un grand nombre de commandes avec lesquelles vous pouvez empêcher la construction d’échouer et Cmake vous informera que, par exemple, vous n’avez pas de bibliothèques boost filesystem et regex installées. sur votre système. Pour ce faire, vous pouvez utiliser la syntaxe suivante:

find_package(Boost 1.45.0 COMPONENTS filesystem regex)

Après avoir vérifié qu'il générera les fichiers Make pour le système/IDE/compilateur approprié.

12
Patryk