Inhaltsverzeichnis
CMake
Um aus C++-Quelltexten ausführbare Programme zu machen, sind je nach System andere Schritte notwendig. In Entwicklungsumgebungen werden Projekte erstellt, Quelltexte registriert, Einstellungen für das Projekt vorgenommen. Beschreibungen “klicke hier, klicke da, drücke F5” erspare ich mir. Auch Kommandozeilenbefehle unterscheiden sich je nach Compiler (g++
, cl
, make
, nmake
, …).
Das Ziel von CMake (cross-platform make) ist, den Übersetzungsvorgang compiler- und systemunabhängig zu automatisieren. Modern CMake formuliert den Bau von Projekten über Targets und deren Eigenschaften, vom Finden benötigter Bibliotheken und Pakete bis zu Installation und Continuous Integration.
Ein erstes Projekt erstellen
CMake beschreibt das Projekt in menschenlesbarer Form. In der Datei CMakeLists.txt
folgen nach Versionsanforderung und Projektname die zu erzeugenden Ziele (Targets). Das einzige Ziel hier ist das ausführbare programm
, dessen Quelltext sich im Unterverzeichnis src
befindet:
cmake_minimum_required(VERSION 3.18) project(beispiel) # zu erzeugende Ziele + deren Quellen: add_executable(programm src/quelltext.cpp)
Zum Übersetzen sollte ein getrenntes Verzeichnis build
für die von CMake erzeugten Dateien angelegt werden. Dort werden das Projekt konfiguriert, Programm(e) übersetzt und bei Erfolg ausgeführt:
mkdir build # Verzeichnis anlegen cd build # und hinein wechseln cmake -G "MinGW Makefiles" .. # Projekt erzeugen: hier Makefiles cmake --build . # Projekt übersetzen programm # ausführen
Der Befehl cmake ..
genügt für den von CMake voreingestellten Compiler. Soll ein anderes Build-System zum Einsatz kommen, wird als Option -G "Name des Generators"
angegeben. cmake --help
liefert eine Liste verfügbarer Generatoren. Falls die Erzeugung des Projektes scheitert, einfach build
-Verzeichnis komplett löschen und von vorn beginnen.
Für spätere Änderungen am Projekt entfällt die Angabe des Generators:
cmake .. # bei Änderungen an CMakeLists.txt cmake --build . # bei Änderungen am Quelltext cmake --build . --target programm # wenn nur ein bestimmtes Ziel erreicht werden soll
Als Targets dienen auch all
(baue alle Ziele), clean
(übersetzte Dateien entfernen), help
(zeigt Liste erreichbarer Ziele an) oder test
(Tests mit CTest durchführen, sofern definiert).
C++-Version vorgeben
Den Sprachstandard kann man vor allen Zielen global festlegen (C++20 kennt CMake ab Version 3.12, C++17 ab 3.8):
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF)
Bei komplexeren Projekten empfiehlt sich die Angabe für jedes Ziel separat
set_target_properties(myTarget PROPERTIES CXX_STANDARD 20 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF )
oder über erforderliche Compiler-Merkmale (siehe Dokumentation zu CMAKE_CXX_KNOWN_FEATURES):
target_compile_features(myTarget PRIVATE cxx_std_20)
Mehrere Dateien
Mehrere Quellen werden bei der Festlegung des Ziels aufgeführt oder später ergänzt:
add_executable(programm quelle1.cpp quelle2.cpp) target_sources(programm zusatzquelle1.cpp zusatzquelle2.cpp)
Verzeichnisse wie src
und include
(relativ zu CMakeLists.txt
) werden mit diesen Befehlen gefunden:
target_include_directories(programm include) target_source_directories(programm src)
Bibliotheken erstellen und einbinden
Auch Bibliotheken sind Ziele in CMake:
add_library(libname libsrcfiles) # Bibliothek erzeugen target_link_libraries(programm libname) # Bibliothek einbinden
Unterprojekte bauen
Unterverzeichnisse mit eigener CMakeLists.txt
erlauben komplexe Projekte mit rekursiver Struktur:
add_subdirectory(dirname)