C++-Projekte mit CMake

2017-07-27

Makefiles von Hand schreiben ist einfach nur nervig. Je mehr Dateien das Projekt hat, umso nerviger wird es korrekte Abhängigkeiten oder Unittests zu pflegen. Die Liste an Alternativen zu GNU Make ist natürlich sehr lang. Da ich in der Regel nur C++-Projekte unter Linux bauen will, landete ich letztendlich bei CMake. Dabei erzeugt CMake in meinem Fall auch nur wieder ein Makefile, ach die Ironie.

Aufteilung

Das Beispiel hier zeigt einen Auszug für ein Programm, das in einen Library-Teil mylib und einen Executable-Teil myprg aufgeteilt ist. Den Einstieg enthält dann die Datei main.cpp und wird gegen mylib gelinkt. Die statische Bibliothek kann man später genauso nutzen um gegen die Unittests zu linken.

# target CMakeLists.txt
add_library(mylib STATIC
    DataItem.cpp
    DataItemManager.cpp
)
add_executable(myprg main.cpp)
target_link_libraries(myprog mylib)

Unity Build

Unity Builds sind auch als Single Compilation Unit Builds bekannt und können die Kompilierzeit verkürzen und bessere Optimierungen ermöglichen. Mit einem Modul wie cotire ist es mit wenigen Zeilen eingerichtet. Man erhält damit neue Build-Targets, die auf _unity enden.

# top level CMakeLists.txt
include(cotire)
# target CMakeLists.txt
cotire(myprg)

Testabdeckung

Mit Unittests bin ich eher bereit größere Änderungen am Code vorzunehmen. Damit man mögliche Regressionen sehr früh findet, sollten die Unittest möglichst alle/viele Pfade abdecken. Auch für die Testabdeckung gibt es ein passendes CMake-Modul. Mit nur drei Zeilen gibt es ein weiteres Maketarget coverage dafür.

# top level CMakeLists.txt
include(CodeCoverage)
APPEND_COVERAGE_COMPILER_FLAGS()
SETUP_TARGET_FOR_COVERAGE(NAME "coverage" EXECUTABLE "unittest")

Statische Analyse

Zur statischen Code-Analyse mit cppcheck genügt das Erzeugen der Kompilierungs-Kommandos, da es CMake bereits unterstützt.

$ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
$ cppcheck --project=compile_commands.json

Ich bin sehr zufrieden mit CMake und seinen Möglichkeiten. Letztendlich kopiere ich mir zwar immer noch die nötigen Dateien aus alten Projekten zusammen und am Ende führe ich ein Makefile aus, aber alles funktioniert zuverlässig und ich habe nützliche Zusatzfunktionen, die ich niemals selbst mit make umgesetzt hätte. Selbst Boost wird auf CMake umsatteln. So erwarte ich eine noch besser Unterstützung von C++ in der Zukunft.

Tags: Code, CMake, C++

Kommentare? Tweet