Wie genau funktioniert CMake?

156

Ich frage das nicht nur für mich. Ich hoffe, diese Frage ist eine Referenz für die vielen Neulinge, die mich mögen, und fand es äußerst verwirrend, was genau hinter den Kulissen vor sich ging, wenn es um eine so kleine CMakeLists.txtDatei ging

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

und so ein kleiner tutorial.cpp

int main() { return 0; } 

Es werden so viele Dateien generiert

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

und ein CMakeFilesOrdner mit so vielen Dateien und Ordnern

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

Das größte Hindernis beim Erlernen von CMake bestand darin, nicht zu verstehen, was sich hinter den Kulissen abspielte (dh warum möglicherweise Dateien generiert werden mussten und welchen Zweck sie hatten).

Wenn jemand weiß, können Sie es bitte der Nachwelt zuliebe erklären? Was ist der Zweck dieser Dateien und cmake .was genau konfiguriert und generiert cmake beim Erstellen, bevor ich das Projekt erstelle?

Nav
quelle
1
Mir sind Out-of-Source-Builds bekannt. Falls jemand keinen Out-of-Source-Build durchgeführt hat und immer noch nach einer Möglichkeit sucht, generierte Dateien zu bereinigen, funktioniert diese Technik gut: stackoverflow.com/a/12055610/453673
Nav
3
Es gibt eine wunderbare Beschreibung unter: aosabook.org/en/cmake.html und wahrscheinlich eine ausführliche Antwort auf die Frage (die hier nicht kurz zusammengefasst werden kann).
Parasrish
@SebTu Defekter Link. Die Seite cmake.html existiert nicht.
Nav
3
@Nav Yap, hat die Markup-Syntax durcheinander gebracht, sorry. Daher hier die korrigierte Version: Für Leute, die neu in cmake sind, empfehle ich wirklich, die Architektur von cmake zu lesen . Es bietet gerade genug Informationen, um ein Gefühl dafür zu bekommen, wie cmake funktioniert, ohne sich in Details zu verlieren.
SebNag

Antworten:

91

Das Geheimnis ist, dass Sie nicht verstehen müssen, was die generierten Dateien tun.

CMake bringt eine Menge Komplexität in das Build-System, von denen sich die meisten nur dann auszahlen, wenn Sie es zum Erstellen komplexer Softwareprojekte verwenden.

Die gute Nachricht ist, dass CMake einen Großteil dieser Unordnung von Ihnen fernhält: Verwenden Sie Builds außerhalb der Quelle, und Sie müssen sich nicht einmal die generierten Dateien ansehen. Wenn Sie dies bisher nicht getan haben (was seit Ihrem Schreiben der Fall ist cmake .), überprüfen Sie es bitte, bevor Sie fortfahren . Das Mischen des Build- und Quellverzeichnisses ist bei CMake sehr schmerzhaft und nicht die Art und Weise, wie das System verwendet werden soll.

Kurz gesagt: Statt

cd <source_dir>
cmake .

Verwenden Sie immer

cd <build_dir_different_from_source_dir>
cmake <source_dir>

stattdessen. Normalerweise verwende ich einen leeren Unterordner buildin meinem Quellverzeichnis als Erstellungsverzeichnis.

Lassen Sie mich einen kurzen Überblick über die relevanten Dateien geben, die CMake generiert, um Ihre Schmerzen zu lindern:

  • Projektdateien / Makefiles - Was Sie tatsächlich interessiert: Die Dateien, die zum Erstellen Ihres Projekts unter dem ausgewählten Generator erforderlich sind. Dies kann alles sein, von einem Unix-Makefile bis zu einer Visual Studio-Lösung.
  • CMakeCache.txt - Dies ist ein persistenter Schlüssel- / Wertzeichenfolgenspeicher, der zum Zwischenspeichern von Werten zwischen Läufen verwendet wird. Hier gespeicherte Werte können Pfade zu Bibliotheksabhängigkeiten sein oder ob überhaupt eine optionale Komponente erstellt werden soll. Die Liste der Variablen ist größtenteils identisch mit der, die Sie beim Ausführen von ccmakeoder sehen cmake-gui. Dies kann von Zeit zu Zeit nützlich sein, aber ich würde empfehlen, die oben genannten Tools zu verwenden, um nach Möglichkeit einen der Werte zu ändern.
  • Generierte Dateien - Dies kann alles sein, von automatisch generierten Quelldateien bis hin zu Exportmakros, mit denen Sie Ihr erstelltes Projekt wieder in andere CMake-Projekte integrieren können. Die meisten davon werden nur auf Anfrage generiert und erscheinen nicht in einem einfachen Projekt wie dem aus Ihrer Frage.
  • Alles andere ist ziemlich laut, um das Build-System zufrieden zu stellen. Insbesondere musste ich mich nie um irgendetwas kümmern, das im CMakeFilesUnterverzeichnis vor sich geht.

Im Allgemeinen sollten Sie sich nicht mit den Dateien herumschlagen, die CMake für Sie generiert. Alle Probleme können auf die CMakeLists.txteine oder andere Weise von innen gelöst werden . Solange das Ergebnis Ihr Projekt wie erwartet erstellt, geht es Ihnen wahrscheinlich gut. Sorgen Sie sich nicht zu sehr um die blutigen Details - denn CMake hat versucht, Ihnen dies zu ersparen.

ComicSansMS
quelle
Vielen Dank. War sich der Out-of-Source-Builds bewusst, aber wie Sie sehen würden, bestand das Ziel dieser Frage darin, mehr zu verstehen. Der CMakeCache.txt-Teil Ihrer Antwort hat wirklich geholfen. Es ist diese Art von Erklärung, nach der ich gesucht habe. Auch der letzte Satz meiner Frage: " Was genau konfiguriert und generiert cmake, bevor es das Projekt erstellt? "
Nav
1
CMakeFilesVerzeichnis enthält CMakeError.logund CMakeOutput.logwichtig für die Fehlerbehebung bei CMake-Builds.
Serge Rogatch
1
Zwei Dinge, die Sie manchmal im CMakeFiles/target_name.dirVerzeichnis einchecken müssen, sind die flags.makeund link.txt-Dateien. Ich musste diese in einem komplexen Projekt überprüfen, das Flags / Linked-Stuff von Upstream-Projekten geerbt hat. Beispiel: Ich hatte einige Fehler, weil TPL A von TPL B abhängig war. Auch mein Projekt hatte eine Abhängigkeit von B, die ich lokal installiert habe. Aber A verwendete eine Version von B von meinem System (anstelle meiner lokalen Installation), die verschiedene aktivierte Optionen hatte, und sie kam zuerst und verursachte Fehler in meinem Projekt. Nur durch einen Blick auf link.txt konnte ich herausfinden, dass dies geschah.
Bartgol
12

Wie auf seiner Website angegeben:

Cmake ist ein plattformübergreifendes Open-Source-Build-System zur Verwaltung des Build-Prozesses von Software mithilfe einer compilerunabhängigen Methode

In den meisten Fällen wird es zum Generieren von Projekt- / MakefileErstellungsdateien verwendet - in Ihrem Beispiel wurden Dateien erstellt, die zum Erstellen Ihrer Software verwendet werden (hauptsächlich auf Linux / Unix-Plattformen).

Mit Cmake können plattformübergreifende Build-Dateien bereitgestellt werden, die plattformspezifische Projekt- / Make-Dateien für eine bestimmte Kompilierung / Plattform generieren.

Sie können beispielsweise versuchen, Ihre Software unter Windows mit Visual Studio zu kompilieren, und dann mit der richtigen Syntax in Ihrer CMakeLists.txtDatei starten

cmake .

Im Verzeichnis Ihres Projekts auf der Windows-Plattform generiert Cmake alle erforderlichen Projekt- / Lösungsdateien ( .slnusw.).

Wenn Sie Ihre Software auf einer Linux / Unix-Plattform erstellen möchten, gehen Sie einfach in das Quellverzeichnis, in dem Sie Ihre CMakeLists.txtDatei haben, und lösen Sie diese aus. cmake .Es werden alle Dateien generiert, die Sie zum Erstellen von Software über einfach makeoder einfach benötigen make all.

Hier haben Sie eine sehr gute Präsentation über die wichtigsten Cmake-Funktionen http://www.elpauer.org/stuff/learning_cmake.pdf

BEARBEITEN

Wenn Sie plattformabhängige Bibliothekseinschlüsse / Variablendefinitionen usw. CMakeLists.txterstellen möchten, können Sie diese Syntax in einer Datei verwenden

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

Es gibt auch viele Befehle, mit deren Hilfe Sie verhindern können, dass der Build fehlschlägt. Cmake benachrichtigt Sie an Ort und Stelle, dass Sie beispielsweise keine Boost-Bibliotheken haben filesystemund regexauf Ihrem System installiert sind. Dazu können Sie die folgende Syntax verwenden:

find_package(Boost 1.45.0 COMPONENTS filesystem regex)

Nachdem überprüft wurde, dass die Makefiles für das entsprechende System / IDE / Compiler generiert werden.

Patryk
quelle
1
Danke Patryk. Eine hilfreiche Antwort, aber das PDF, auf das Sie verlinkt haben, erklärt hauptsächlich die zweite Phase des Lernens von CMake, bei der es sich im Wesentlichen um die Implementierung von CMake handelt. Ich frage nach der Erklärung der ersten Phase, in der eine Person verstehen muss, was in aller Welt in CMake vor sich geht!
Nav
@Nav Ich habe meine Antwort ein wenig erweitert. Sie können weiterhin im Internet nach weiteren Informationen suchen.
Patryk
Dies ist weit davon entfernt, die gestellte Frage zu beantworten.
SenhorLucas
1

Wie CMake genau funktioniert, ist eine Frage für die Entwickler, daher kann diese Frage hier nicht beantwortet werden.

Wir können Ihnen jedoch nützliche Hinweise geben, wann Sie CMake verwenden sollten und wann Sie sich daher Gedanken darüber machen müssen, wie es funktioniert. Ich bin auch kein Fan von "Oh, es funktioniert einfach" -Antworten - denn gerade in der Software funktioniert NICHTS jemals "nur" und Sie müssen IMMER irgendwann auf die Details eingehen.

CMake ist ein industrietaugliches Werkzeug. Es automatisiert mehrere SEHR komplexe Prozesse und berücksichtigt viele Variablen, die Sie möglicherweise nicht kennen, insbesondere als relativ neuer Entwickler, der wahrscheinlich mit begrenzten Kenntnissen aller Betriebssysteme und Build-Tools arbeitet, die CMake verarbeiten kann. Der Grund, warum so viele Dateien generiert werden und warum die Dinge so komplex erscheinen, liegt darin, dass all diese anderen Systeme komplex sind und berücksichtigt und automatisiert werden müssen. Darüber hinaus gibt es die Probleme des "Caching" und anderer zeitsparender Funktionen des Tools. Um alles in CMake zu verstehen, muss man alles in diesen Build-Tools und Betriebssystemen sowie alle möglichen Kombinationen dieser Variablen verstehen, was, wie Sie sich vorstellen können, unmöglich ist.

Es ist wichtig zu beachten, dass die Verwendung von CMake ein bisschen wie die Entfernung von 100.000-Dollar-Forstbäumen erscheint, wenn Sie nicht für die Verwaltung eines großen plattformübergreifenden Build-Systems verantwortlich sind und Ihre Codebasis ein paar KLOC beträgt, möglicherweise bis zu 100KLOG Maschine zum Entfernen von Unkraut aus Ihrem 2 Fuß mal 2 Fuß großen Blumengarten. (Übrigens, wenn Sie noch nie eine solche Maschine gesehen haben, sollten Sie auf Youtube nach einer suchen, sie ist unglaublich)

Wenn Ihr Build-System klein und einfach ist, ist es wahrscheinlich besser, Ihre eigenen Makefiles von Hand zu schreiben oder sie selbst zu skripten. Wenn Ihre Makefiles unhandlich werden oder Sie eine Version Ihres Systems auf einer anderen Plattform erstellen müssen, können Sie zu CMake wechseln. An diesem Punkt müssen Sie viele Probleme lösen und Sie können gezieltere Fragen dazu stellen. Schauen Sie sich in der Zwischenzeit einige der großartigen Bücher an, die über CMake geschrieben wurden, oder schreiben Sie noch besser selbst eines! 8)

Herr Jeps
quelle