Verschil tussen het gebruik van Makefile en CMake om de code te compileren

Ik codeer op C/C++ en gebruik een (GNU) Makefile om de code te compileren. Ik kan hetzelfde doen met CMake en een MakeFile krijgen. Wat is echter het verschil tussen Makefile en CMake gebruiken om de code te compileren?


Antwoord 1, autoriteit 100%

Make (of liever een Makefile) is een bouwsysteem – het stuurt de compiler en andere bouwhulpmiddelen aan om uw code te bouwen.

CMake is een generator van bouwsystemen. Het kan Makefiles produceren, het kan Ninja-buildbestanden produceren, het kan KDEvelop- of Xcode-projecten produceren, het kan Visual Studio-oplossingen produceren. Vanaf hetzelfde startpunt, hetzelfde CMakeLists.txt-bestand. Dus als je een platformonafhankelijk project hebt, is CMake een manier om het ook systeemonafhankelijk te maken.

Als je Windows-ontwikkelaars hebt die gewend zijn aan Visual Studio- en Unix-ontwikkelaars die zweren bij GNU Make, dan is CMake (een van) de juiste keuze.

Ik zou altijd aanraden om CMake (of een andere buildsystem-generator, maar CMake is mijn persoonlijke voorkeur) te gebruiken als je van plan bent om je project multi-platform of breed inzetbaar te maken. CMake zelf biedt ook enkele leuke functies, zoals afhankelijkheidsdetectie, bibliotheekinterfacebeheer of integratie met CTest, CDash en CPack.

Het gebruik van een buildsystem-generator maakt uw project toekomstbestendiger. Zelfs als je nu alleen GNU-Make gebruikt, wat als je later besluit om uit te breiden naar andere platforms (of het nu Windows is of iets ingebed), of gewoon een IDE wilt gebruiken?


Antwoord 2, autoriteit 17%

De bewering dat CMake een “build-generator” is, is een veel voorkomende misvatting.

Het is technisch niet verkeerd; het beschrijft alleen HOE het werkt, maar niet WAT het doet.

In de context van de vraag doen ze hetzelfde: een aantal C/C++-bestanden nemen en ze omzetten in een binair bestand.

Dus, wat is het echte verschil?

  • CMake is veel hoger. Het is op maat gemaakt om C++ te compileren, waarvoor je veel minder buildcode schrijft, maar het kan ook worden gebruikt voor algemene builds. makeheeft ook enkele ingebouwde C/C++-regels, maar die zijn op zijn best nutteloos.

  • CMakedoet een build in twee stappen: het genereert een low-level build-script in ninjaof makeof vele andere generatoren, en dan laat je het draaien. Alle shellscript-stukken die normaal in Makefileworden gestapeld, worden alleen uitgevoerd in de generatiefase. Zo kan de build van CMakeorden van grootte sneller zijn.

  • De grammatica van CMakeis veel gemakkelijker te ondersteunen voor externe tools dan make’s.

  • Zodra makeeen artefact bouwt, vergeet het hoe het is gebouwd. Uit welke bronnen is het opgebouwd, welke vlaggen van de compiler? CMakevolgt het, makelaat het aan jou over. Als een van de bibliotheekbronnen is verwijderd sinds de vorige versie van Makefile, zal makehet niet opnieuw opbouwen.

  • Moderne CMake(vanaf versie 3.something) werkt in termen van afhankelijkheden tussen “doelen”. Een doel is nog steeds een enkel uitvoerbestand, maar het kan transitieve (“public”/”interface” in CMake-termen) afhankelijkheden hebben.
    Deze transitieve afhankelijkheden kunnen worden blootgesteld aan of verborgen voor de afhankelijke pakketten. CMakezal mappen voor u beheren. Met makezit je vast op een bestand-voor-bestand en beheer-directories-by-hand niveau.

Je zou iets kunnen coderen in makemet tussenliggende bestanden om de laatste twee gaten te dichten, maar je staat er alleen voor. makebevat een Turing volledige taal(zelfs twee, soms drie tellen Guile); de eerste twee zijn verschrikkelijk en de Guile wordt praktisch nooit gebruikt.

Om eerlijk te zijn, dit is wat CMakeen makegemeen hebben — hun talen zijn behoorlijk afschuwelijk. Dit komt in je op:

  • Ze hebben geen door de gebruiker gedefinieerde typen;
  • CMakeheeft drie gegevenstypen: tekenreeks, lijst en een doel met eigenschappen. makeheeft één: string;
  • u geeft normaal gesproken argumenten door aan functies door globale variabelen in te stellen.
    • Dit wordt gedeeltelijk opgelost in moderne CMake – u kunt de eigenschappen van een doel instellen: set_property(TARGET helloworld APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}");
  • verwijzen naar een ongedefinieerde variabele wordt standaard stilzwijgend genegeerd;

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Other episodes