Debug vs Release dans CMake

437

Dans un projet compilé par GCC,

  • Comment exécuter CMake pour chaque type de cible (débogage / version)?
  • Comment spécifier les indicateurs de débogage et de libération C / C ++ à l'aide de CMake?
  • Comment puis-je exprimer que l'exécutable principal sera compilé avec g++et une bibliothèque imbriquée avec gcc?
Cartesius00
la source

Réponses:

660

Avec CMake, il est généralement recommandé de faire une build "hors source" . Créez votre CMakeLists.txtà la racine de votre projet. Puis à partir de la racine de votre projet:

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

Et pour Debug(encore une fois à partir de la racine de votre projet):

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

Release/ Debugajoutera les drapeaux appropriés pour votre compilateur. Il existe également des configurations RelWithDebInfoet MinSizeRelconstruire.


Vous pouvez modifier / ajouter aux indicateurs en spécifiant un fichier de chaîne d'outils dans lequel vous pouvez ajouter CMAKE_C_FLAGS_DEBUGet des CMAKE_C_FLAGS_RELEASEvariables, par exemple:

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall")

Voir CMAKE_BUILD_TYPE pour plus de détails.


Quant à votre troisième question, je ne sais pas exactement ce que vous demandez. CMake devrait automatiquement détecter et utiliser le compilateur approprié pour vos différents fichiers source.

kb1ooo
la source
3
Vous pouvez également faire un à la cmake -i ..place, afin que cmake s'exécute de manière interactive, vous demandant quel type de build vous souhaitez (None, Release, Debug, MinSizeRel, RelWithDebInfo).
thiagowfx
5
@thiagowfx -ioptions de ce message d'erreur: The "cmake -i" wizard mode is no longer supported.. J'utilise cmake 3.7.1
Philipp Claßen
3
Belle observation. Il semble qu'il soit obsolète depuis la version 3.0.0. Référence .
thiagowfx
7
Ce n'est PAS une version hors source si vous créez un sous-répertoire! Il est conseillé de créer le répertoire de construction en dehors / au-dessus du répertoire source.
Victor Lamoine
Notez que si CMAKE_BUILD_TYPEn'est pas défini, cmake ne choisira aucun type de build par défaut, donc la ligne de commande du compilateur généré ne correspondra à aucune configuration de build.
david
23

Pour les indicateurs de débogage / libération, voir la CMAKE_BUILD_TYPEvariable (vous la passez comme cmake -DCMAKE_BUILD_TYPE=value). Il prend des valeurs telles que Release, Debug, etc.

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

cmake utilise l'extension pour choisir le compilateur, il suffit donc de nommer vos fichiers .c.

Vous pouvez remplacer cela avec différents paramètres:

Par exemple:

set_source_files_properties(yourfile.c LANGUAGE CXX) 

Compilerait des fichiers .c avec g ++. Le lien ci-dessus montre également comment sélectionner un compilateur spécifique pour C / C ++.

duncan
la source
16

Au lieu de manipuler CMAKE_CXX_FLAGSdirectement les chaînes (ce qui pourrait être mieux fait en utilisant string(APPEND CMAKE_CXX_FLAGS_DEBUG " -g3")btw), vous pouvez utiliser add_compiler_options:

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

Cela ajouterait les avertissements spécifiés à tous les types de build, mais seulement les drapeaux de débogage donnés à la DEBUGbuild. Notez que les options de compilation sont stockées sous forme de liste CMake, qui n'est qu'une chaîne séparant ses éléments par des points-virgules ;.

Sébastien
la source
2
list(APPEND CMAKE_CXX_FLAGS_DEBUG "-g3")N'ajoutera pas de point-virgule avant que -g3 ne termine la commande et démarre une nouvelle commande -g3 qui échouera sûrement?
cburn11
Vous avez raison CMAKE_CXX_FLAGSn'est pas une liste cmake mais une chaîne d'indicateurs de ligne de commande séparés par des espaces. Je trouve ce comportement incohérent ...
sebastian
add_compile_options () est soigné. Il est complété par add_link_options () lorsque vous devez également ajouter des options à l'éditeur de liens, telles que -fsanitize = adresse.
Bowie Owens
1
Est-ce toujours la manière appropriée en 2020 / cmake 3.17? Cette dernière ligne a l'air méchante
Jay
8

Si vous souhaitez créer une configuration différente sans régénérer si vous utilisez, vous pouvez également exécuter cmake --build {$PWD} --config <cfg>Pour les outils de configuration multiple, choisissez <cfg>ex. Debug, Release, MinSizeRel, RelWithDebInfo

https://cmake.org/cmake/help/v2.8.11/cmake.html#opt%3a--builddir

Russel Waters
la source
J'ai essayé de jouer avec --configoption sans aucun résultat. Il n'affecte pas la $<CONFIG>variable comme le -DCMAKE_BUILD_TYPE=fait.
loshad vtapkah
5

// CMakeLists.txt: libération

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

// CMakeLists.txt: débogage

set(CMAKE_CONFIGURATION_TYPES "Debug" CACHE STRING "" FORCE)
sailfish009
la source
10
je ne comprends pas pourquoi ce vote est voté, c'est du vrai code qui est utilisé dans la production, btw je m'en fiche.
sailfish009
5
Peut-être parce que selon les documents CMake CMAKE_CONFIGURATION_TYPEScontient les valeurs possibles pour CMAKE_BUILD_TYPE. Vous devez donc définir ce dernier comme le suggèrent les autres réponses. Peut-être que votre solution fonctionne car elle limite les choix possibles à celui que vous aimeriez avoir.
bjhend
2
Votez parce que cela fonctionnera. Je m'aime certains CMake mais il y a des bizarreries et parfois vous devez utiliser un gros marteau pour faire fonctionner les choses. J'ai certains projets qui, pour une raison ou une autre, rejetteront l'indicateur de ligne de commande.
cory.todd
Voici quelques informations supplémentaires sur les raisons pour lesquelles le paramètre peut ne pas fonctionner: stackoverflow.com/a/24470998/3196753
tresf