namespace cpp

C++ lernen, kennen, anwenden

Benutzer-Werkzeuge

Webseiten-Werkzeuge


lernen:cmake

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)
lernen/cmake.txt · Zuletzt geändert: 2020-08-23 20:03 von rrichter