Définir la macro du préprocesseur via CMake?

283

Comment définir une variable de préprocesseur via CMake?

Le code équivalent serait #define foo.

Mythli
la source

Réponses:

383

Pendant longtemps, CMake avait la add_definitionscommande à cet effet. Cependant, récemment, la commande a été remplacée par une approche plus fine (commandes distinctes pour compiler les définitions, inclure les répertoires et les options du compilateur).

Un exemple utilisant les nouvelles add_compile_definitions :

add_compile_definitions(OPENCV_VERSION=${OpenCV_VERSION})
add_compile_definitions(WITH_OPENCV2)

Ou:

add_compile_definitions(OPENCV_VERSION=${OpenCV_VERSION} WITH_OPENCV2)

La bonne partie à ce sujet est qu'il contourne la supercherie minable que CMake a mise en place add_definitions. CMake est un tel système minable, mais ils trouvent enfin un peu de raison.

Trouvez plus d'explications sur les commandes à utiliser pour les drapeaux du compilateur ici: https://cmake.org/cmake/help/latest/command/add_definitions.html

De même, vous pouvez faire cela par cible comme expliqué dans la réponse de Jim Hunziker.

ypnos
la source
4
À partir de la page liée: "Remarque Cette commande a été remplacée par des alternatives: utilisez add_compile_definitions () pour ajouter des définitions de préprocesseur." Peut-être que cette réponse nécessite une modification?
M.Herzkamp
10
Dans cmake 3.10.2, add_compile_definitionsjette CMake Error at CMakeLists.txt:6 (add_compile_definitions): Unknown CMake command "add_compile_definitions".. J'ai dû utiliser à la add_compile_options(-D <your-def>)place.
code_dredd
2
@mannyglover Je ne pense pas, mais vous pouvez définir les drapeaux du compilateur avec -D, quelque chose comme cmake -D CMAKE_CXXFLAGS='-DDEBUG_CHESSBOARD'(non testé)
ypnos
1
C'est vraiment nouveau ... en fait c'est dans More Modern CMake (> 3.11). Une douleur qu'il est si difficile de savoir quand une commande a été introduite.
Sandburg
1
@Sandburg Vous pouvez ouvrir le lien vers la dernière documentation: https://cmake.org/cmake/help/v3.17/command/add_compile_definitions.html#command:add_compile_definitionset commencer à changer le numéro de version jusqu'à ce que la page disparaisse. Ce serait la version là où elle n'existe pas encore. Dans le prochain mouvement, vous pouvez aller à la Whats newsection pour trouver une nouvelle commande ou fonctionnalité. Donc ce n'est pas si difficile.
Andry
245

Pour ce faire, pour une cible spécifique, vous pouvez effectuer les opérations suivantes:

target_compile_definitions(my_target PRIVATE FOO=1 BAR=1)

Vous devriez le faire si vous avez plusieurs cibles que vous construisez et que vous ne voulez pas qu'elles utilisent toutes les mêmes indicateurs. Voir également la documentation officielle sur target_compile_definitions .

Jim Hunziker
la source
1
@JimHunziker En quoi est-ce target_compile_definitions(my_target PRIVATE FOO=1)différent de set_source_files_properties(foo.cpp PROPERTIES COMPILE_DEFINITIONS -DFOO=1)?
John Strood
1
@JohnStrood La différence se situe au niveau de la portée. target_compile_definitionsdéfinit la valeur de l'exécutable / bibliothèque WHOLE, où as 'set_source_files_properties` définit la valeur uniquement pour le fichier spécifié. La dernière commande permet de compiler des fichiers dans une autre langue; à savoir: set_source_files_properties(compile_me_as_objc.c PROPERTIES -x objective-c. Notez que -x objective-cvoici un drapeau spécifique à GCC / Clang.
Julian Kirsch
20

Les autres solutions proposées sur cette page sont utiles sur certaines versions de Cmake <3.3.2 . Voici la solution pour la version que j'utilise (ie, 3.3.2). Vérifiez la version de votre Cmake en utilisant $ cmake --versionet choisissez la solution qui correspond à vos besoins. La documentation de cmake se trouve sur la page officielle.

Avec CMake version 3.3.2, afin de créer

#define foo

J'avais besoin d'utiliser:

add_definitions(-Dfoo)   # <--------HERE THE NEW CMAKE LINE inside CMakeLists.txt
add_executable( ....)
target_link_libraries(....)

et, afin d'avoir une définition de macro de préprocesseur comme celle-ci:

#define foo=5

la ligne est ainsi modifiée:

add_definitions(-Dfoo=5)   # <--------HERE THE NEW CMAKE LINE inside CMakeLists.txt
add_executable( ....)
target_link_libraries(....)
Leos313
la source
4
Selon la documentation , cette solution est en fait l'approche la plus ancienne et la plus ancienne. Les autres réponses offrent les solutions les plus modernes.
squareskittles
2
Quand j'ai écrit la réponse, j'ai essayé l'autre solution mais aucune ne fonctionnait.
Leos313
@squareskittles, une idée pourquoi la solution de l'autre réponse n'a pas fonctionné correctement? CMake donne des erreurs si je les essaie
Leos313
1
Si vous utilisez CMake 3.3.2, comme vous l'avez indiqué dans votre réponse, vous devez utiliser add_definitions()ou target_compile_definitions(). La commande plus moderne,, add_compile_definitions()n'a pas été ajoutée avant CMake 3.12. @ Leos313
squareskittles
1
@squareskittles, je mets à jour la réponse, en réécrivant ce que j'ai écrit il y a quelques mois. Merci d'avoir souligné cela
Leos313