Au début de mon projet CMake, je mets des drapeaux de compilation généraux dans la variable CMAKE_CXX_FLAGS, comme
set(CMAKE_CXX_FLAGS "-W -Wall ${CMAKE_CXX_FLAGS}")
Plus tard, je dois ajouter des indicateurs de compilation spécifiques à la configuration supplémentaires (stockés dans BUILD_FLAGS). Puis-je utiliser la commande suivante pour cela:
set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS ${BUILD_FLAGS})
ou dois-je ajouter les CMAKE_CXX_FLAGS manuellement:
set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${BUILD_FLAGS}")
pour éviter que CMAKE_CXX_FLAGS soit remplacé par BUILD_FLAGS?
Utilisez le premier:
set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS ${BUILD_FLAGS})
Les drapeaux stockés dans BUILD_FLAGS sont ajoutés après CMAKE_CXX_FLAGS lors de la compilation des sources de TARGET. La documentation y fait allusion, mais je viens de l'essayer pour m'en assurer.
COMPILE_FLAGS
Additional flags to use when compiling this target's sources. The COMPILE_FLAGS property sets additional compiler flags used to build sources within the target. Use COMPILE_DEFINITIONS to pass additional preprocessor definitions.
La ligne de commande complète sera l'équivalent de:
${CMAKE_CXX_COMPILER} ${CMAKE_CXX_FLAGS} ${COMPILE_FLAGS} -o foo.o -c foo.cc
Et comme l'a dit Ramon, vous pouvez toujours vérifier avec make VERBOSE=1
.
La réponse acceptée réponse fonctionne toujours mais est obsolète depuis 2013.
Cette réponse est basée sur de nouvelles fonctions de CMake v2.8.12, v3.3 et v3.13.
Deux nouvelles commandes pour définir CMAKE_CXX_FLAGS
:
target_compile_options()
(pour une seule cible)add_compile_options()
(pour toutes les cibles)La documentation de la dernière version n'a pas beaucoup changé depuis cmake-2.8.12 :
Dans votre cas, vous pouvez utiliser:
target_compile_options(${TARGET} PRIVATE ${BUILD_FLAGS})
Ou tout simplement si vous n'avez qu'une seule cible:
add_compile_options(${BUILD_FLAGS})
target_compile_options(mylib PRIVATE -O2) # only internal
target_compile_options(mylib INTERFACE -gl) # only external
target_compile_options(mylib PUBLIC -g) # same as PRIVATE + INTERFACE
# multiple targets and flags
target_compile_options(mylib1 mylib2 PRIVATE -Wall -Wextra)
target_compile_options( mylib PUBLIC -DUSEXX) # Bad
target_compile_definitions(mylib PUBLIC -DUSEXX) # OK
add_compile_options(-Wall -Wextra) # for all targets in current directory
add_compile_options(-DUSEXX) # Bad
add_definitions(-DUSEXX) # OK
COMPILE_FLAGS
documentation cmake-3.0 drapeaux COMPILE_FLAGS
comme obsolète:
COMPILE_FLAGS
Indicateurs supplémentaires à utiliser lors de la compilation des sources de cette cible.
La propriété
COMPILE_FLAGS
Définit des indicateurs de compilateur supplémentaires utilisés pour créer des sources dans la cible. UtilisezCOMPILE_DEFINITIONS
Pour passer des définitions de préprocesseur supplémentaires.Cette propriété est obsolète. Utilisez à la place la propriété
COMPILE_OPTIONS
Ou la commandetarget_compile_options
.
Si vous souhaitez toujours utiliser set_target_properties()
vous pouvez utiliser COMPILE_OPTIONS
Au lieu de COMPILE_FLAGS
:
set_target_properties(${TARGET} PROPERTIES COMPILE_OPTIONS ${BUILD_FLAGS})
Anton Petrov suggère d'utiliser expressions de générateur comme présenté dans un réponse de ar31 .
Les expressions du générateur CMake appliquent votre ${BUILD_FLAGS}
À:
$<COMPILE_LANGUAGE:CXX>
(Peut également être C
, CUDA
...)$<CXX_COMPILER_ID:Clang>
GNU
pour gcc
, ou MSVC
pour Visual C++ ... voir liste complète )$<C_COMPILER_ID:Clang>
si la langue est C)Dans votre cas, vous pouvez utiliser:
target_compile_options(${TARGET} PRIVATE
$<$<COMPILE_LANGUAGE:CXX>:${BUILD_FLAGS_FOR_CXX}>
$<$<COMPILE_LANGUAGE:C>:${BUILD_FLAGS_FOR_C}>)
ou sur les compilateurs:
target_compile_options(${TARGET} PRIVATE
$<$<CXX_COMPILER_ID:Clang>:${BUILD_FLAGS_FOR_CLANG}>
$<$<CXX_COMPILER_ID:GNU>:${BUILD_FLAGS_FOR_GCC}>
$<$<CXX_COMPILER_ID:MSVC>:${BUILD_FLAGS_FOR_VISUAL}>)
Une nouvelle fonction target_link_options()
permet de passer des options à l'éditeur de liens, comme mentionné par Craig Scott .
La meilleure façon est de distinguer les fichiers C et les fichiers C++ en utilisant deux cibles différentes.