Comment fonctionne exactement CMake?

158

Je ne demande pas ça uniquement pour moi. J'espère que cette question sera une référence pour les nombreux débutants qui, comme moi, ont trouvé cela complètement perplexe quant à ce qui se passait exactement dans les coulisses quand pour un si petit CMakeLists.txtfichier

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

et 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 CMakeFilesdossier avec tant 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'est-à-dire pourquoi des fichiers devaient être générés et quel était leur but), était le plus grand obstacle pour pouvoir apprendre 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 lorsque je tape cmake ., qu'est-ce que cmake configure et génère exactement avant de générer le projet?

Nav
la source
1
Je connais les versions hors source. Dans le cas où quelqu'un n'a pas fait une compilation hors source et cherche toujours un moyen de nettoyer les fichiers générés, cette technique fonctionne bien: stackoverflow.com/a/12055610/453673
Nav
3
Il y a une merveilleuse description sur: aosabook.org/en/cmake.html et probablement une réponse approfondie à la question (qui ne peut être résumée en bref ici).
parasrish
@SebTu Lien brisé. La page cmake.html n'existe pas.
Nav
3
@Nav Yap, a foiré la syntaxe de balisage, désolé. Ainsi, voici la version corrigée: Pour les nouveaux utilisateurs de cmake, je recommande vraiment de lire l' architecture de cmake . Il fournit juste assez d'informations pour avoir une idée du fonctionnement de cmake sans se perdre dans les détails.
SebNag

Réponses:

92

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 sont payants que si vous l'utilisez pour créer des projets logiciels complexes.

La bonne nouvelle est que CMake fait un bon travail pour garder une grande partie de ce désordre loin de vous: utilisez des compilations hors source et vous n'avez même pas besoin de regarder 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 construction et le répertoire source est vraiment 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 builddans mon répertoire source comme 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 de 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 n'importe quoi, d'un Makefile Unix à une solution Visual Studio.
  • CMakeCache.txt - Il s'agit d'un stockage de chaîne clé / valeur persistante qui est utilisé pour mettre en cache la valeur entre les exécutions. Les valeurs stockées ici peuvent être des chemins vers les dépendances de bibliothèque ou si un composant facultatif doit être créé. La liste des variables est pratiquement identique à celle que vous voyez lors de l'exécution de ccmakeou cmake-gui. Cela peut être utile à regarder de temps en temps, mais je recommanderais d'utiliser les outils mentionnés ci-dessus pour changer l'une des valeurs si possible.
  • Fichiers générés - Cela peut être n'importe quoi, des fichiers sources générés automatiquement aux macros d'exportation qui vous aident à réintégrer votre projet généré avec d'autres projets CMake. La plupart d'entre eux ne sont générés qu'à la demande et n'apparaîtront pas dans un projet simple tel que celui de votre question.
  • Tout le reste est à peu près bruyant pour garder le système de construction heureux. En particulier, je n'ai jamais eu besoin de me soucier de tout ce qui se passe dans le CMakeFilessous - répertoire.

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

ComicSansMS
la source
Merci. Était au courant des builds hors source, mais comme vous le verrez, l'objectif de poser cette question était de mieux comprendre. La partie CMakeCache.txt de votre réponse a vraiment aidé. C'est ce genre d'explication que je cherchais. Aussi, la dernière phrase de ma question: " qu'est-ce que cmake configure et génère exactement avant de construire le projet "
Nav
1
CMakeFilesLe répertoire contient CMakeError.loget est CMakeOutput.logimportant pour le dépannage des builds CMake.
Serge Rogatch
1
Deux choses que vous devez parfois archiver dans le CMakeFiles/target_name.dirrépertoire sont les fichiers flags.makeet link.txt. J'ai dû les vérifier dans un projet complexe, qui a hérité des indicateurs / éléments liés des projets en amont. Par exemple: j'ai eu des erreurs parce que TPL A avait une dépendance sur TPL B. De plus, mon projet avait une dépendance sur B, que j'ai installé localement; mais A a utilisé une version de B de mon système (plutôt que mon installation locale) qui avait différentes options activées, et elle est venue en premier, provoquant des erreurs dans mon projet. En regardant seulement link.txt, j'ai pu découvrir que cela se passait.
bartgol
13

Comme indiqué sur son site Web:

Cmake est un système de construction open source multiplateforme pour gérer le processus de construction de logiciels à l'aide d'une méthode indépendante du compilateur

Dans la plupart des cas, il est utilisé pour générer des fichiers projet / make - dans votre exemple, il a produit Makefilequi sont utilisés pour construire votre logiciel (principalement sur la plate-forme Linux / Unix).

Cmake permet de fournir des fichiers de construction multiplateformes qui généreraient des fichiers de projet / de création spécifiques à la plate-forme pour une compilation / plate-forme particulière.

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

cmake .

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

Si vous souhaitez créer votre logiciel sur une plate-forme Linux / Unix, vous devez simplement aller dans le répertoire source où vous avez votre CMakeLists.txtfichier et déclencher le même cmake .et il générera tous les fichiers nécessaires pour que vous puissiez créer un logiciel via simple makeou 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 rendre la bibliothèque dépendante de la plate-forme comprend / définitions de variables, etc., vous pouvez utiliser cette syntaxe dans le CMakeLists.txtfichier

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

Il existe également de nombreuses commandes avec lesquelles vous pouvez empêcher la compilation d'échouer et, en place, Cmake vous avertira que, par exemple, vous n'avez pas de bibliothèques boost filesystemet regexinstallé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 makefiles pour le système / IDE / compilateur approprié.

Patryk
la source
1
Merci Patryk. Réponse utile, mais le pdf auquel vous avez lié, explique principalement la deuxième étape de l'apprentissage de CMake, qui est essentiellement la mise en œuvre de CMake. Je demande l'explication de la première étape, où une personne doit comprendre ce qui se passe dans CMake!
Nav
@Nav J'ai un peu élargi ma réponse. Vous pouvez toujours rechercher sur le Web pour plus d'informations.
Patryk
C'est bien loin de répondre à la question posée.
SenhorLucas le
1

Comment fonctionne CMake exactement est une question pour les développeurs, donc cette question ne peut pas être répondue ici.

Cependant, nous pouvons vous donner quelques conseils utiles pour savoir quand utiliser CMake et quand vous devez donc vous soucier de son fonctionnement. Je ne suis pas non plus fan des réponses "oh ça marche juste" - parce que, en particulier dans les logiciels, RIEN ne "fonctionne juste" et il faut TOUJOURS entrer dans les détails à un moment donné.

CMake est un outil de puissance industrielle. Il automatise plusieurs processus TRÈS complexes et prend en compte de nombreuses variables dont vous n'êtes peut-être pas au courant, en particulier en tant que développeur relativement nouveau, travaillant probablement avec une connaissance limitée de tous les systèmes d'exploitation et des outils de construction que CMake peut gérer. La raison pour laquelle tant de fichiers sont générés et pourquoi les choses semblent si complexes est que tous ces autres systèmes sont complexes et doivent être pris en compte et automatisés. De plus, il y a les problèmes de «mise en cache» et d'autres fonctionnalités de l'outil qui permettent de gagner du temps.

Il est important de noter que si vous n'êtes pas en charge de la gestion d'un grand système de construction multiplateforme et que votre base de code est quelques KLOC, peut-être jusqu'à 100KLOG, utiliser CMake semble un peu comme utiliser un élimination d'arbres forestiers de 100000 dollars. machine pour éliminer les mauvaises herbes de votre jardin de fleurs de 2 pieds sur 2 pieds. (Au fait, si vous n'avez jamais vu une telle machine, vous devriez en chercher une sur youtube, elles sont incroyables)

Si votre système de construction est petit et simple, il sera probablement préférable d'écrire vos propres makefiles à la main ou de les script vous-même. Lorsque vos makefiles deviennent peu maniables ou que vous devez créer une version de votre système sur une autre plate-forme, vous pouvez basculer vers CMake. À ce stade, vous aurez beaucoup de problèmes à résoudre et vous pourrez poser des questions plus ciblées à ce sujet. En attendant, consultez quelques-uns des grands livres qui ont été écrits sur CMake, ou mieux encore, écrivez-en un vous-même! 8)

Monsieur Jeps
la source