web-dev-qa-db-fra.com

Modification de CMAKE_CXX_FLAGS dans le projet

J'ai le contenu suivant dans mon CMakeLists.txt:

project( Matfile )

SET ( CMAKE_CXX_FLAGS "-std=c++0x" )

set ( SOURCES
      "foo.cpp"
      "bar.cpp"
    )

add_library(
        Matfile
        ${SOURCES}
)

Comme vous pouvez l’imaginer, je souhaite compiler mes sources C++ à l’aide de l’indicateur -std = c ++ 0x (j’utilise gcc et j’ai besoin des fonctionnalités C++ 11). Malheureusement, cela ne fonctionne pas, dans le sens où, lorsque j'utilise cmake pour générer les fichiers makefiles, la variable CMAKE_CXX_FLAGS est complètement nulle.

Comment définir cette variable dans le fichier de projet?

Cela semble être une question très stupide, mais je viens de passer pas moins de deux heures à essayer de comprendre cela.

34
Spiros

La manière correcte de définir la norme C++ dans CMake 3.1 et versions ultérieures est la suivante:

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED on)

Il est possible de spécifier la norme pour une cible individuelle aussi:

set_property(TARGET mylib PROPERTY CXX_STANDARD 11)

Depuis CMake 3.8, il existe une option new dans la commande target_compile_features qui permet de définir le standard requis pour une cible:

target_compile_features(mylib PUBLIC cxx_std_11)

L'avantage serait qu'il propage l'exigence aux cibles dépendantes. Si vous compilez une bibliothèque avec la fonctionnalité cxx_std_11 requise, tous les fichiers binaires qui y sont liés auront automatiquement cette exigence définie.

12
Cris Luengo

Est-il utile d’utiliser le drapeau FORCE?

SET ( CMAKE_CXX_FLAGS "-std=c++0x" CACHE STRING "compile flags" FORCE)
12
Christopher Bruns

Peut-être que cela fonctionnerait mieux:

set_source_files_properties(${SOURCES}
       PROPERTIES
       COMPILE_FLAGS  "-std=c++0x")
5
Christopher Bruns

Pour développer un peu ADD_COMPILE_OPTIONS () avec l'expression du générateur answer by ar31, vous pouvez rencontrer un problème lorsque vous souhaitez ajouter plusieurs indicateurs séparés par des espaces, car cmake a un bogue nasty dans les expressions du générateur .

La solution que j'ai utilisée était une boucle FOREACH, voici un exemple du projet sur lequel je travaille:

IF(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    # common flags
    SET(MY_C_AND_CXX_FLAGS -mtune=generic -pipe -fPIC -Wformat -Wformat-security -fomit-frame-pointer -fstack-protector-strong --param ssp-buffer-size=4 -fexceptions -D_FORTIFY_SOURCE=2 -feliminate-unused-debug-types)

    SET(MY_C_FLAGS   ${MY_C_FLAGS}   ${MY_C_AND_CXX_FLAGS})
    SET(MY_CXX_FLAGS ${MY_CXX_FLAGS} ${MY_C_AND_CXX_FLAGS})

    IF(MINGW)
        SET(MY_C_FLAGS   ${MY_C_FLAGS}   -static-libgcc)
        SET(MY_CXX_FLAGS ${MY_CXX_FLAGS} -static-libgcc -static-libstdc++)
    ENDIF(MINGW)

    IF(CMAKE_BUILD_TYPE STREQUAL "Debug")
        SET(MY_C_FLAGS   ${MY_C_FLAGS}   -g2 -Wall)
        SET(MY_CXX_FLAGS ${MY_CXX_FLAGS} -g2 -Wall)
    ELSE()
        SET(MY_C_FLAGS   ${MY_C_FLAGS}   -O2 -Wno-error)
        SET(MY_CXX_FLAGS ${MY_CXX_FLAGS} -O2 -Wno-error)
    ENDIF()

    FOREACH(C_COMPILE_FLAG ${MY_C_FLAGS})
        ADD_COMPILE_OPTIONS($<$<COMPILE_LANGUAGE:C>:${C_COMPILE_FLAG}>)
    ENDFOREACH()

    FOREACH(CXX_COMPILE_FLAG ${MY_CXX_FLAGS})
        ADD_COMPILE_OPTIONS($<$<COMPILE_LANGUAGE:CXX>:${CXX_COMPILE_FLAG}>)
    ENDFOREACH()

    # for the gcc -fstack-protector* flags we need libssp
    # clang does not have this
    IF(CMAKE_COMPILER_IS_GNUCXX)
        SET(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -lssp")
        SET(CMAKE_C_LINK_EXECUTABLE   "${CMAKE_C_LINK_EXECUTABLE}   -lssp")
    ENDIF()
ENDIF()

# Assembler flags

IF(ASM_ENABLED)
    FOREACH(ASM_FLAG -I${CMAKE_SOURCE_DIR}/src/filters/hq/asm/ -O1 -w-Orphan-labels)
        ADD_COMPILE_OPTIONS($<$<COMPILE_LANGUAGE:ASM_NASM>:${ASM_FLAG}>)
    ENDFOREACH()
ENDIF(ASM_ENABLED)
2
Rafael Kitover

Dans le cas particulier où un compilateur est requis, cmake 3.1 résout le problème en fournissant un moyen de demander une version standard ou un ensemble de fonctionnalités du compilateur. Reportez-vous à cette réponse et à la documentation officielle .

2
Spiros

consultez les ucm_add_flags et ucm_print_flags macros de ucm - pour ajouter des indicateurs de compilateur aux variables cmake appropriées et examiner les résultats.

1
onqtam

C'est la solution que j'utilise actuellement:

if(CMAKE_COMPILER_IS_GNUCXX)
    add_definitions(-std=c++0x)
    add_definitions(-std=gnu++11)
endif()

Ou, si vous avez une version plus ancienne de cmake et que vous voulez le voir apparaître dans cmake-gui:

set_property(CACHE CMAKE_CXX_FLAGS PROPERTY VALUE "-std=c++0x")
0
user2364011

J'ai mis au point une meilleure méthode qui fonctionne avec les anciennes versions de cmake, par exemple. Ubuntu 14 a 2.8.12, et les expressions cibles sont 3.3.

Voici comment définir des indicateurs spécifiques à C++:

STRING(REGEX REPLACE "<FLAGS>" "<FLAGS> -std=gnu++11 -fpermissive -fexceptions " CMAKE_CXX_COMPILE_OBJECT ${CMAKE_CXX_COMPILE_OBJECT})
0
Rafael Kitover