web-dev-qa-db-fra.com

Set_target_properties dans CMake remplace-t-il CMAKE_CXX_FLAGS?

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?

54
Milan Hanus

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.

52
richq

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.

Depuis CMake-2.8.12 (2013)

Deux nouvelles commandes pour définir CMAKE_CXX_FLAGS:

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})

Plus d'exemples

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

Obsolète 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. Utilisez COMPILE_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 commande target_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})

Depuis CMake-3.3 (2015)

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} À:

  • Langage C++ utilisant $<COMPILE_LANGUAGE:CXX> (Peut également être C, CUDA...)
  • Compilateur Clang utilisant $<CXX_COMPILER_ID:Clang>
    (peut également être GNU pour gcc, ou MSVCpour Visual C++ ... voir liste complète )
    (utilisez plutôt $<C_COMPILER_ID:Clang> si la langue est C)
  • et plus comme fonction C++ prise en charge ou version du compilateur ... (voir documentation )

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}>)

Depuis CMake-3.13 (2018)

Une nouvelle fonction target_link_options() permet de passer des options à l'éditeur de liens, comme mentionné par Craig Scott .

Différentes options pour les fichiers C et C++

La meilleure façon est de distinguer les fichiers C et les fichiers C++ en utilisant deux cibles différentes.

49
olibre