Ich habe mich gefragt, ob es einen Beispielcode für Makefile
s ( make
) und CMakeLists.txt
( cmake
) gibt, die beide dasselbe tun (der einzige Unterschied besteht darin, dass einer in make
und der andere in geschrieben ist cmake
).
Ich habe versucht, nach 'cmake vs make' zu suchen, aber ich habe keine Codevergleiche gefunden. Es wäre wirklich hilfreich, die Unterschiede zu verstehen, auch wenn es sich nur um einen einfachen Fall handelt.
cmake
wollte ich das auch. Aber ich bezweifle, dass Sie es finden werden, weil die Funktionen einfach nicht so gut aufeinander abgestimmt sind. Wenn Sie versuchen, sich so zucmake
verhaltenmake
, werden Sie sich ernsthaft verrückt machen. Am besten einfach von vorne anfangen. Dinge, die trivialmake
sind, sind ziemlich involviertcmake
und umgekehrt.make
undcmake
sind sie so unterschiedlich, dass sie eher als komplementäre als als konkurrierende Werkzeuge angesehen werden sollten?cp *.x $(OUTDIR)
Sie in ein Makefile schreiben würden, ziemlich kompliziert . Der vielleicht nervigste Teil für mich ist, dass die generierten Makefiles von Natur aus völlig unportabel und unflexibel sind (Fortsetzung)Antworten:
Das folgende Makefile baut eine ausführbare Datei namens
prog
aus den Quellenprog1.c, prog2.c, prog3.c and main.c
.prog
ist gegenlibmystatlib.a
undlibmydynlib.so
die beide auch aus der Quelle erstellt werden. Darüber hinausprog
verwendet die Bibliotheklibstuff.a
instuff/lib
und seinen Header instuff/include
. Das Makefile erstellt standardmäßig ein Release-Ziel, bietet aber auch ein Debug-Ziel:Hier ist eine
CMakeLists.txt
, die (fast) genau das Gleiche tut, mit einigen Kommentaren, um die Ähnlichkeiten mit dem Makefile zu unterstreichen:In diesem einfachen Beispiel sind die wichtigsten Unterschiede:
CMake erkennt, welche Compiler für welche Art von Quelle verwendet werden sollen. Außerdem wird für jeden Zieltyp die richtige Befehlsfolge aufgerufen. Daher gibt es keine explizite Angabe von Befehlen wie
$(CC) ...
,$(RANLIB) ...
und so weiter.Alle üblichen Compiler- / Linker-Flags, die sich mit der Aufnahme von Header-Dateien, Bibliotheken usw. befassen, werden durch plattformunabhängige / systemunabhängige Build-Befehle ersetzt.
Debugging-Flags werden eingeschlossen, indem die Variable entweder
CMAKE_BUILD_TYPE
auf "Debug" gesetzt oder beim Aufrufen des Programms an CMake übergeben wird :cmake -DCMAKE_BUILD_TYPE:STRING=Debug
.CMake bietet auch die plattformunabhängige Aufnahme des '-fPIC'-Flags (über die
POSITION_INDEPENDENT_CODE
Eigenschaft) und vieler anderer. Noch dunkelere Einstellungen können in CMake genauso wie in einem Makefile von Hand implementiert werden (unter VerwendungCOMPILE_FLAGS
ähnlicher Eigenschaften). Natürlich beginnt CMake wirklich zu glänzen, wenn Bibliotheken von Drittanbietern (wie OpenGL) auf tragbare Weise enthalten sind.Der Erstellungsprozess besteht aus einem Schritt, wenn Sie ein Makefile verwenden, nämlich der Eingabe
make
über die Befehlszeile. Für CMake gibt es zwei Schritte: Erstens müssen Sie Ihre Build-Umgebung einrichten (entweder durch Eingabecmake <source_dir>
in Ihr Build-Verzeichnis oder durch Ausführen eines GUI-Clients). Dadurch wird je nach Build-System Ihrer Wahl ein Makefile oder etwas Ähnliches erstellt (z. B. make unter Unixes oder VC ++ oder MinGW + Msys unter Windows). Das Build-System kann als Parameter an CMake übergeben werden. CMake trifft jedoch abhängig von Ihrer Systemkonfiguration angemessene Standardentscheidungen. Zweitens führen Sie den eigentlichen Build im ausgewählten Build-System durch.Quellen und Build-Anweisungen finden Sie unter https://github.com/rhoelzel/make_cmake .
quelle
CPPFLAGS
anstelle vonINCDIR
hätte man die eingebauten Regeln verwenden können und der explizite Aufruf des Compilers wäre überflüssig gewesen. In ähnlicher Weise können die eingebauten Regeln für den Umgang mit ar auch dies abdecken. Auch warum setzenCPP
undCC
explizit? Sie sind bereits auf gute Werte eingestelltmake
, sie sind vordefinierte Variablen.make
erkennt auch, welcher Compiler für welche Art von Quelle verwendet werden soll, die integrierten Regeln sind vielfältig.:=
statt zugewiesen werden=
.cmake
ist vergleichbarerautomake
alsmake
.INCLUDES
anstelle von angebenINCDIR
. Sie benötigen keine% .o:%. C-Regeln.Besorgen Sie sich eine Software, die CMake als Buildsystem verwendet (als Beispiel stehen zahlreiche Open Source-Projekte zur Auswahl). Holen Sie sich den Quellcode und konfigurieren Sie ihn mit CMake. Lesen Sie die resultierenden Makefiles und genießen Sie.
Beachten Sie, dass diese Tools nicht eins zu eins zugeordnet werden. Der offensichtlichste Unterschied besteht darin, dass CMake nach Abhängigkeiten zwischen verschiedenen Dateien sucht (z. B. C-Header- und Quelldateien), während make dies den Makefile-Autoren überlässt.
quelle
Wenn es sich bei dieser Frage um ein Beispiel handelt
Makefile
derCMakeList.txt
Datei handelt, überprüfen Sie bitte die cmake-Backend-Quellen und generieren Sie eine solcheMakefile
. Wenn dies nicht der Fall ist, versuche ich, die Antwort von @Roberto zu vereinfachen, indem ich die Details verstecke.CMake-Funktion
Während
Make
es ein flexibles Werkzeug für Regeln und Rezepte ist,CMake
ist es eine Abstraktionsebene, die auch die Konfigurationsfunktion hinzufügt.Meine Ebene
CMakeLists.txt
wird wie folgt aussehen:Beachten Sie, dass sich
CMake
versteckthow
der Build getan werden kann. Wir haben nurwhat
die Ein- und Ausgabe angegeben.Das
CMakeLists.txt
enthält eine Liste von Funktionsaufrufen, die durch definiert sindcmake
.(CMake-Funktion) Vs Regeln erstellen
In
Makefile
derrules and recipes
werden statt verwendetfunctions
.function
Stellen Sie zusätzlich zu einer ähnlichen Funktionrules and recipes
eine Verkettung bereit. Mein MinimalistMakefile
sieht wie folgt aus:Während das
executable.mk
wie folgt aussehen wird,Ausgehend von Grund auf beginne ich mit einem
Makefile
wie folgt:Ich habe diesen Ausschnitt von hier bekommen und es modifiziert. Beachten Sie, dass dieser Datei einige implizite Regeln hinzugefügt werden, die in der Makefile-Dokumentation zu finden sind. Einige implizite Variablen sind auch hier relevant.
Beachten Sie, dass
Makefile
das Detailrecipe
zeigt , dasshow
der Build ausgeführt werden kann. Es ist möglich zu schreibenexecutable.mk
, um die Details in einer Datei zu behalten. Auf diese Weise kann das Makefile reduziert werden, wie ich zuvor gezeigt habe.Interne Variablen in
CMake
undMake
Jetzt, da
CMake
wir ein wenig fortgeschritten sind, können wir ein Compiler-Flag wie das folgende setzen:Weitere Informationen zu
CMake
Standardvariablen finden Sie in derCMakeCache.txt
Datei. DerCMake
obige Code entspricht dem folgendenMake
Code.Beachten Sie, dass
CFLAGS
eine interne VariableMake
, die gleiche Art und Weise,CMAKE_C_FLAGS
ist die interne VariableCMake
.Hinzufügen von Include- und Bibliothekspfad in CMake
Wir können es
cmake
mit Funktionen tun .Vs Hinzufügen von Include- und Bibliothekspfad in Make
Wir können Include- und Bibliotheken hinzufügen, indem wir Zeilen wie die folgenden hinzufügen:
Beachten Sie, dass diese obigen Zeilen mit Auto-Gen-Tools oder pkg-config generiert werden können. (obwohl Makefile nicht von Auto-Config-Tools abhängig ist)
CMake configure / tweek
Normalerweise ist es möglich, einige
config.h
Dateien wieauto-config
Werkzeuge mithilfe derconfigure_file
Funktion zu generieren . Es ist möglich, benutzerdefinierte Funktionen mit mehr Tricks zu schreiben. Und schließlich können wir eine Konfiguration wie die folgende auswählen:Mit der
option
Funktion können einige konfigurierbare Optionen hinzugefügt werden.Makefile konfigurieren / optimieren
Wenn wir es irgendwie mit einem Debug-Flag kompilieren müssen, können wir das Gleiche aufrufen
make
,Ich denke, interne Variablen,
Makefile-rules
undCMake-functions
sind ein guter Anfang für den Vergleich, viel Glück mit mehr Graben.quelle