Es gibt zwei Arten von Generatoren: Einzelkonfigurationen und Mehrfachkonfigurationen.
Einzelne Konfigurationen
Make-like-Generatoren: Unix-Makefiles , NMake-Makefiles , MinGW-Makefiles , ...
Den Konfigurationstyp legen Sie im Generierungsschritt fest:
cmake -H. -B_builds/Debug -DCMAKE_BUILD_TYPE=Debug "-GUnix Makefiles"
In diesem Fall lautet der Erstellungsschritt immer Debug :
> cmake --build _builds/Debug
/usr/bin/c++ -g ...
> cmake --build _builds/Debug --config Debug # `--config` ignored
/usr/bin/c++ -g ...
> cmake --build _builds/Debug --config Release # yep, ignored
/usr/bin/c++ -g ...
Multi-Konfiguration
IDE-Generatoren: Visual Studio , Xcode
CMAKE_BUILD_TYPE
Beim Generieren wird der Schritt ignoriert. Beide:
> cmake -H. -B_builds -DCMAKE_BUILD_TYPE=Debug "-GVisual Studio 12 2013 Win64"
und
> cmake -H. -B_builds -DCMAKE_BUILD_TYPE=Release "-GVisual Studio 12 2013 Win64"
wird den gleichen Effekt haben:
Dies liegt daran, dass alle Konfigurationen intern sind (dh _builds/msvc-opaque/Release
und _builds/msvc-opaque/Debug
oder etwas spielt keine Rolle). Sie können --config
Optionen verwenden, um zu wechseln:
> cmake --build _builds --config Release
cl /O2 ...
> cmake --build _builds --config Debug
cl /Od ...
Steuerung (?)
Ja, du kannst. Definieren Sie einfach CMAKE_CONFIGURATION_TYPES :
# Somewhere in CMakeLists.txt
message("Generated with config types: ${CMAKE_CONFIGURATION_TYPES}")
Standardausgabe:
-- Detecting CXX compiler ABI info - done
Generated with config types: Debug;Release;MinSizeRel;RelWithDebInfo
-- Configuring done
Schreiben Sie es um:
> cmake -H. -B_builds -DCMAKE_CONFIGURATION_TYPES="Debug;Release" "-GVisual Studio 12 2013 Win64"
-- Detecting CXX compiler ABI info - done
Generated with config types: Debug;Release
-- Configuring done
Sie können sogar Ihren eigenen Konfigurationstyp definieren:
> cmake -H. -B_builds -DCMAKE_CONFIGURATION_TYPES="Debug;MyRelease" -DCMAKE_CXX_FLAGS_MYRELEASE="/My-Rel-flag" -DCMAKE_EXE_LINKER_FLAGS_MYRELEASE="/My-Linker-flags" "-GVisual Studio 12 2013 Win64"
Und bauen:
cmake --build _builds --config MyRelease
Chaotisch (?)
Überhaupt nicht, wenn Sie den Trick kennen :) So erstellen / testen Sie die Konfiguration in den Erstellungsanweisungen eines Skripts / CI-Servers / der Dokumentation usw.:
> CONFIG=Debug
> cmake -H. -B_builds "-DCMAKE_BUILD_TYPE=${CONFIG}" # Set Debug to Makefile, ignored by IDE
> cmake --build _builds --config "${CONFIG}" # Build Debug in IDE, ignored by Makefile
> (cd _builds && ctest -VV -C "${CONFIG}") # Test Debug in IDE, ignored by Makefile
Schlechtes Muster
if(CMAKE_BUILD_TYPE STREQUAL Debug) # Burn it with fire!!!
set(CMAKE_BUILD_TYPE MySuperRelease) # Be ready to catch a bug from IDE user...
Gut
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} --my-debug-flags")
Funktioniert gut.
target_compile_definitions(MyTarget PUBLIC "$<$<CONFIG:Debug>:MYDEBUG_MACRO>")
Vielen Dank! :) Sie sparen einen Tag für einen Programmierer.
Arbeitet für mich mit Makefile, ich bin glücklich ...
Ein Zitat aus einem schönen Buch eines netten Mannes, den Sie wahrscheinlich kennen (Hervorhebung von mir):
Warum sollten Sie sich die Mühe machen? Menschen, die auf einer Vielzahl von Systemen programmieren oder eine Vielzahl von Compilern verwenden, kümmern sich sehr darum, denn wenn sie dies nicht tun, müssen sie Zeit damit verschwenden , obskure Fehler zu finden und zu beheben. Leute, die behaupten, dass ihnen Portabilität egal ist, tun dies normalerweise, weil sie nur ein einziges System verwenden und das Gefühl haben, sich die Einstellung leisten zu können, dass die Sprache das ist, was mein Compiler implementiert. Dies ist eng und kurzsichtigAussicht. Wenn Ihr Programm erfolgreich ist, wird es wahrscheinlich portiert, sodass jemand Probleme im Zusammenhang mit implementierungsabhängigen Funktionen finden und beheben muss. Darüber hinaus müssen Programme häufig mit anderen Compilern für dasselbe System kompiliert werden, und selbst eine zukünftige Version Ihres bevorzugten Compilers kann einige Dinge anders machen als die aktuelle. Es ist viel einfacher, die Auswirkungen von Implementierungsabhängigkeiten beim Schreiben eines Programms zu kennen und zu begrenzen, als danach zu versuchen, das Chaos zu entwirren.