579 Stimmen

Debuggen vs. Freigeben in CMake

In einem GCC-kompilierten Projekt,

  • Wie führe ich CMake für jeden Zieltyp (Debug/Release) aus?
  • Wie kann ich mit CMake Debug- und Release-Flags für C/C++ angeben?
  • Wie bringe ich zum Ausdruck, dass die ausführbare Hauptdatei mit g++ und eine verschachtelte Bibliothek mit gcc ?

858voto

kb1ooo Punkte 8102

Mit CMake wird im Allgemeinen empfohlen, eine "aus der Quelle" bauen . Erstellen Sie Ihr CMakeLists.txt in der Wurzel Ihres Projekts. Dann von der Wurzel Ihres Projekts:

mkdir Release
cd Release
cmake -DCMAKE_BUILD_TYPE=Release ..
make

Und für Debug (wiederum von der Wurzel Ihres Projekts aus):

mkdir Debug
cd Debug
cmake -DCMAKE_BUILD_TYPE=Debug ..
make

Release / Debug fügt die entsprechenden Flags für Ihren Compiler hinzu. Außerdem gibt es RelWithDebInfo y MinSizeRel Konfigurationen erstellen.


Sie können die Flags ändern/ergänzen, indem Sie eine Toolchain-Datei in dem Sie Folgendes hinzufügen können CMAKE_<LANG>_FLAGS_<CONFIG>_INIT Variablen, z.B.:

set(CMAKE_CXX_FLAGS_DEBUG_INIT "-Wall")
set(CMAKE_CXX_FLAGS_RELEASE_INIT "-Wall")

Siehe CMAKE_BUILD_TYPE für weitere Einzelheiten.


Was Ihre dritte Frage betrifft, bin ich mir nicht sicher, was Sie genau fragen. CMake sollte automatisch den für Ihre verschiedenen Quelldateien geeigneten Compiler erkennen und verwenden.

71voto

Viele der Antworten hier sind veraltet/schlecht. Deshalb werde ich versuchen, sie besser zu beantworten. Zugegeben, ich beantworte diese Frage im Jahr 2020, es ist also zu erwarten, dass sich die Dinge ändern werden.


Wie führe ich CMake für jeden Zieltyp (Debug/Release) aus?

Zunächst einmal werden Debug/Release in cmake als Konfigurationen bezeichnet (Erbsenzähler).

Wenn Sie einen einzelnen Konfigurationsgenerator (Ninja/Unix-Makefiles) verwenden, müssen Sie die CMAKE_BUILD_TYPE .

Zum Beispiel so:

# Configure the build
cmake -S . -B build/ -D CMAKE_BUILD_TYPE=Debug

# Actually build the binaries
cmake --build build/

# Configure a release build
cmake -S . -B build/ -D CMAKE_BUILD_TYPE=Release

# Build release binaries
cmake --build build/

Bei Generatoren mit mehreren Konfigurationen ist die Situation etwas anders (Ninja Multi-Config, Visual Studio)

# Configure the build
cmake -S . -B build

# Build debug binaries
cmake --build build --config Debug

# Build release binaries
cmake --build build --config Release

Wenn Sie sich fragen, warum das notwendig ist, liegt das daran, dass cmake kein Build-System ist. Es ist ein Meta-Build-System (IE ein Build-System, das Build-Systeme baut). Dies ist im Grunde das Ergebnis der Handhabung von Build-Systemen, die mehrere Konfigurationen in einem Build unterstützen. Wenn Sie ein tieferes Verständnis wünschen, empfehle ich Ihnen, ein wenig über cmake in Craig Scotts Buch "Professional CMake: A Practical Guide" zu lesen.


Wie kann ich mit CMake Debug- und Release-Flags für C/C++ angeben?

Die moderne Praxis besteht darin, Ziele und Eigenschaften zu verwenden.

Hier ist ein Beispiel:

add_library(foobar)

# Add this compile definition for debug builds, this same logic works for
# target_compile_options, target_link_options, etc.
target_compile_definitions(foobar PRIVATE
    $<$<CONFIG:Debug>:
        FOOBAR_DEBUG=1
    >
)

HINWEIS: Ich verwende Generatorausdrücke, um die Konfiguration festzulegen! Die Verwendung von CMAKE_BUILD_TYPE führt zu fehlerhaften Builds für jeden Multikonfigurationsgenerator!

Außerdem muss man manchmal Dinge global und nicht nur für ein bestimmtes Ziel festlegen. Verwenden Sie add_compile_definitions, add_compile_options, etc. Diese Funktionen unterstützen Generatorausdrücke. Benutzen Sie nicht das alte cmake, wenn Sie nicht müssen (dieser Pfad ist ein Land der Albträume)


Wie drücke ich aus, dass die ausführbare Hauptdatei mit g++ und eine verschachtelte Bibliothek mit gcc kompiliert werden soll?

Ihre letzte Frage ergibt wirklich keinen Sinn.

30voto

duncan Punkte 5817

Für Debug/Release-Flags, siehe die CMAKE_BUILD_TYPE Variable (Sie übergeben sie als cmake -DCMAKE_BUILD_TYPE=value ). Sie nimmt Werte an wie Release , Debug , usw.

https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/Useful-Variables#compilers-and-tools

cmake verwendet die Erweiterung, um den Compiler auszuwählen, also nennen Sie Ihre Dateien einfach .c.

Sie können dies mit verschiedenen Einstellungen außer Kraft setzen:

Zum Beispiel:

set_source_files_properties(yourfile.c LANGUAGE CXX) 

Würde .c-Dateien mit g++ kompilieren. Der obige Link zeigt auch, wie man einen bestimmten Compiler für C/C++ auswählt.

27voto

sebastian Punkte 2218

Statt der Manipulation der CMAKE_CXX_FLAGS Zeichenketten direkt (was mit string(APPEND CMAKE_CXX_FLAGS_DEBUG " -g3") btw), können Sie add_compile_options :

add_compile_options(
  "-Wall" "-Wpedantic" "-Wextra" "-fexceptions"
  "$<$<CONFIG:DEBUG>:-O0;-g3;-ggdb>"
)

Dies würde die angegebenen Warnungen zu allen Build-Typen hinzufügen, aber nur die angegebenen Debugging-Flags zu der DEBUG bauen. Beachten Sie, dass die Kompilieroptionen als CMake-Liste gespeichert werden, die nur eine Zeichenkette ist, deren Elemente durch Semikolons getrennt sind ; .

13voto

sailfish009 Punkte 2206

// CMakeLists.txt: Freigabe

set(CMAKE_CONFIGURATION_TYPES "Release" CACHE STRING "" FORCE)

// CMakeLists.txt: debug

set(CMAKE_CONFIGURATION_TYPES "Debug" CACHE STRING "" FORCE)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X