537 Stimmen

Was ist der Unterschied zwischen der Verwendung eines Makefiles und CMake zum Kompilieren des Codes?

Ich programmiere in C/C++ und verwende ein (GNU) Makefile, um den Code zu kompilieren. Ich kann dasselbe mit CMake tun und ein Makefile erstellen. Was ist jedoch der Unterschied zwischen der Verwendung eines Makefiles und CMake zum Kompilieren des Codes?

728voto

Machen (oder besser gesagt ein Makefile) ist ein Buildsystem - es steuert den Compiler und andere Build-Tools, um Ihren Code zu erstellen.

CMake ist ein Generator von Buildsystemen. Es kann Makefiles erstellen, Ninja-Build-Dateien erstellen, KDEvelop oder Xcode-Projekte erstellen, Visual Studio-Lösungen erstellen. Aus dem gleichen Ausgangspunkt, der gleichen CMakeLists.txt-Datei. Wenn Sie also ein plattformunabhängiges Projekt haben, ist CMake auch eine Möglichkeit, es unabhängig vom Buildsystem zu machen.

Wenn Sie Windows-Entwickler haben, die Visual Studio gewohnt sind, und Unix-Entwickler, die auf GNU Make schwören, ist CMake (einer) der Wege, die Sie gehen können.

Ich würde immer empfehlen, CMake (oder einen anderen Buildsystem-Generator, aber CMake ist meine persönliche Präferenz) zu verwenden, wenn Sie Ihr Projekt plattformübergreifend oder weit verbreitet machen möchten. CMake selbst bietet auch einige nette Funktionen wie Abhängigkeitserkennung, Verwaltung von Bibliotheksschnittstellen oder Integration mit CTest, CDash und CPack.

Die Verwendung eines Buildsystem-Generators macht Ihr Projekt zukunftssicher. Selbst wenn Sie im Moment nur GNU-Make verwenden, was ist, wenn Sie später beschließen, auf andere Plattformen (sei es Windows oder etwas eingebettetes) zu erweitern oder einfach nur eine IDE verwenden möchten?

153voto

Victor Sergienko Punkte 12396

Die Aussage, dass CMake ein "Build-Generator" ist, ist ein häufiges Missverständnis.

Technisch gesehen ist es nicht falsch; es beschreibt nur, WIE es funktioniert, aber nicht, WAS es macht.

Im Kontext der Frage tun sie dasselbe: Sie nehmen eine Reihe von C/C++-Dateien und wandeln sie in ein Binärformat um.

Also, was ist der wirkliche Unterschied?

  • CMake ist viel höherstufiger. Es wurde dafür entwickelt, C++ zu kompilieren, für das Sie viel weniger Build-Code schreiben müssen, kann aber auch für den allgemeinen Build verwendet werden. make hat auch einige integrierte C/C++-Regeln, aber sie sind bestenfalls nutzlos.

  • CMake führt einen zweistufigen Build durch: Es generiert ein Low-Level-Build-Skript in ninja oder make oder vielen anderen Generatoren, und dann führen Sie es aus. Alle Shell-Skript-Teile, die normalerweise in eine Makefile gesteckt werden, werden nur in der Generierungsphase ausgeführt. Daher kann ein CMake-Build um Größenordnungen schneller sein.

  • Die Grammatik von CMake ist für externe Tools einfacher zu unterstützen als die von make.

  • Wenn make ein Artefakt erstellt, vergisst es, wie es erstellt wurde. Aus welchen Quellen wurde es erstellt, welche Compiler-Flags? CMake verfolgt es, make überlässt es Ihnen. Wenn eine Bibliotheksquelle seit der vorherigen Version von Makefile entfernt wurde, wird make sie nicht neu erstellen.

  • Modernes CMake (beginnend mit Version 3.irgendwas) funktioniert in Bezug auf Abhängigkeiten zwischen "Zielen". Ein Ziel ist immer noch eine einzelne Ausgabedatei, kann aber transitive ("öffentliche"/"Schnittstelle" in CMake-Begriffen) Abhängigkeiten haben. Diese transitiven Abhängigkeiten können den abhängigen Paketen freigelegt oder verborgen werden. CMake verwaltet Verzeichnisse für Sie. Mit make sind Sie auf einer Datei-für-Datei- und Verzeichnis-verwaltung-per-Hand-Ebene stecken geblieben.

Sie könnten mit make etwas codieren, indem Sie Zwischendateien verwenden, um die letzten beiden Lücken zu schließen, aber Sie sind auf sich allein gestellt. make enthält eine Turing-vollständige Sprache (sogar zwei, manchmal drei, wenn man Guile zählt); die ersten beiden sind schrecklich und das Guile wird praktisch nie verwendet.

Um ehrlich zu sein, das ist das, was CMake und make gemeinsam haben - ihre Sprachen sind ziemlich schrecklich. Hier ist, was mir einfällt:

  • Sie haben keine benutzerdefinierten Typen;
  • CMake hat drei Datentypen: String, Liste und ein Ziel mit Eigenschaften. make hat nur einen: String;
  • Sie übergeben normalerweise Argumente an Funktionen, indem Sie globale Variablen setzen.
    • Dies wird teilweise in modernem CMake behandelt - Sie können die Eigenschaften eines Ziels setzen: set_property(TARGET helloworld APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}");
  • Auf eine nicht definierte Variable zu verweisen wird standardmäßig stillschweigend ignoriert;

3voto

jpr42 Punkte 227

Wie in den anderen Antworten erwähnt, kann CMake andere Projektdateien generieren. Es bezieht sich auf diese Projekte als Generatoren.

Dies ermöglicht es Benutzern, ihren Build mit einer domänenspezifischen Sprache zu schreiben/beschreiben und den Generator zum Kompilieren des Projekts zu verwenden. Dies führt oft zu einfacherem/besserem Code als das direkte Schreiben in diese Projektdateien.

Ein großer Vorteil ist, dass Benutzer das Tool verwenden können, mit dem sie am vertrautesten sind (Makefiles, Visual Studio, XCode, Ninja, etc). Das ist schön, aber es führt möglicherweise zu Komplexität. Warum also nicht einfach Ninja verwenden?

Die Antwort ist die Geschichte. (Wie üblich in C/C++)

Build-Systeme wie Visual Studio haben Tools, die nur diese Projektdateien akzeptieren.

Zum Beispiel hat Microsoft eine Funktion namens "Static Driver Verifier". Ein Tool zur Analyse des Codes von Kernelmodus-Windows-Treibern. Dieses Tool funktioniert jedoch nur mit Visual Studio-Projekten, da es zusammen mit msbuild arbeitet.

msbuild /t:sdv /p:Inputs="Parameters" Projektdatei /p:Configuration=Konfiguration /p:Platform=Plattform

Wenn Ihr Build-System keine Visual Studio-Projektdateien generieren kann, können Sie das Tool nicht verwenden. Das kann für einige Projekte/Unternehmen ein sehr großes Problem sein.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X