web-dev-qa-db-fra.com

cmake ne compilera pas au standard C++ 11

Je suis novice en C++ et je ne parviens pas à compiler/créer/créer des liens/construire/quoi que ce soit, voyons si quelqu'un peut m'aider J'ai fait des recherches et trouvé d'autres personnes avec des problèmes similaires, mais j'ai essayé leurs solutions sans succès, alors voici:

Un simple programme c ++ qui utilise les fonctionnalités de C++ 11 telles que l’initialisation uniforme, les threads, to_string, etc ... génère des erreurs pour lesquelles "xxx" n’a pas été déclaré dans la portée. Plus précisément, j'aimerais utiliser to_string et l'utiliser dans l'espace de noms std ou plus précisément std::to_string crée l'erreur "to_string" n'est pas membre de STD. Donc, clairement, il ne s'agit pas de compiler avec C++ 11.

Alors voici mon fichier make:

#####################################
cmake_minimum_required (VERSION 2.8)
project (raspicam_test)
find_package(raspicam REQUIRED)
find_package(OpenCV)

IF  ( OpenCV_FOUND AND raspicam_CV_FOUND)
        MESSAGE(STATUS "COMPILING OPENCV TESTS")
        add_executable (main main.cpp)
        #target_compile_features(main PRIVATE cxx_range_for)
        set_property(TARGET main PROPERTY CXX_STANDARD 11)
        target_link_libraries (main ${raspicam_CV_LIBS})
ELSE()
        MESSAGE(FATAL_ERROR "OPENCV NOT FOUND IN YOUR SYSTEM")
ENDIF()
#####################################

Comme vous pouvez le constater, je joue avec OpenCV sur un Raspberry Pi. Mais sans les fonctions C++ 11, le programme compile et ne pose aucun problème. Mais je voudrais ajouter des discussions et autres goodies de C++ 11. J'ai ajouté la ligne set_property(TARGET main PROPERTY CXX_STANDARD_REQUIRED 11) selon la documentation de CMAKE:

https://cmake.org/cmake/help/v3.1/prop_tgt/CXX_STANDARD.html

Et cela n'a fait aucune différence dans les erreurs générées. Je l'ai fait d'abord sans le _REQUIRED et ensuite avec. J'ai aussi essayé target_compile_features() à la place, mais CMAKE est revenu avec "commande CMAKE inconnue".

Autres détails: - Compiler sur un Raspberry Pi 3 sous debian Jessie - Le compilateur CXX est GNU 4.9.2 - CMAKE 3.0.2

8
DrTarr

Dans les versions de CMake antérieures à 3.1, nous utilisons

 add_compile_options(-std=c++11) # CMake 2.8.12 or newer

pour ajouter des options de compilation à l'appel du compilateur, comme décrit dans CMake Docs .

Ce n'est probablement pas aussi portable que celui de la réponse d'Alvaro, mais il est plus lisible et puisque vous êtes sur vous, RasPi, je suppose, GCC et Clang, en tant que compilateurs cibles, suffiront.

Edit: Par souci d'exhaustivité: Dans CMake version 3.1 et plus récent, si vous souhaitez forcer C++ 11, vous avez besoin des lignes suivantes:

set(CMAKE_CXX_STANDARD 11) # C++11...
set(CMAKE_CXX_STANDARD_REQUIRED ON) #...is required...
set(CMAKE_CXX_EXTENSIONS OFF) #...without compiler extensions like gnu++11

Cela active les options pour toutes les cibles pendant la compilation. Si vous voulez contrôler cela plus finement, voyez la réponse d'Alvaro ou le CMake Docs of set_taget_properties(), qui ressemble alors à ceci:

set_target_properties(myTarget PROPERTIES
    CXX_STANDARD 11
    CXX_STANDARD_REQUIRED ON
    CXX_EXTENSIONS OFF
)

Edit: Mais sachez que la prise en charge de C++ 11 dans GCC 4 n’est pas complète et que certains éléments pourraient se comporter différemment du standard défini.

30
Bugfinger

CMake ajoute le support pour les propriétés CXX_STANDARD et CXX_STANDARD_REQUIRED dans la version 3.1 .CXX_STANDARD: prenez l'une des valeurs CMAKE_CXX_STANDARD et elles sont 98, 11 and 14. Si vous passez CXX_STANDARD 11 et que le compilateur ne prend pas en charge c ++ 11 CXX_STANDARD devient 98 automatiquement et cmake ne vous donne aucune erreur Si CXX_STANDARD_REQUIRED est OFF ou non défini. . Si votre valeur spécifique à CXX_STANDARD_REQUIRED "ON" CXX_STANDARD est définie comme une propriété requise pour la construction et que cmake s'en occupe.

Pour pouvoir utiliser CHECK_CXX_COMPILER_FLAG, vous devez inclure le module CheckCXXCompilerFlag:

include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
if(COMPILER_SUPPORTS_CXX11)
    message(STATUS "${COMPILER_SUPPORTS_CXX11}")
else(COMPILER_SUPPORTS_CXX11)
    message(FATAL_ERROR "${COMPILER_SUPPORTS_CXX11}")
endif(COMPILER_SUPPORTS_CXX11)

Si vous avez un vieux cmake vous avez besoin de manipuler des drapeaux compliqués et non portables Des compilateurs sush tels que:

function(suported_compilers)
  if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
    execute_process(
      COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
    if(NOT(GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7))
      message(FATAL_ERROR "${PROJECT_NAME} requires g++ 4.7 or greater.")
    endif(NOT(GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7))
  elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
  else()
    message(FATAL_ERROR "Your compiler is supported in the build set?, please "
                  "contact the maintainer.")
  endif()
endfunction(suported_compilers)
function(set_targets_compilers_flags target_list)
  suported_compilers()
  foreach(tg ${target_list})
    if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
      set_target_properties(${tg} PROPERTIES COMPILE_FLAGS "-g -std=c++14 -Wall -Wextra -Werror")
    elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
      set_target_properties(${tg} PROPERTIES COMPILE_FLAGS "/W4 /WX /EHsc")
    endif()
  endforeach()
endfunction(set_targets_compilers_flags)
4

Comme la version actuelle de cmake est 3.10, j’ai pensé qu’il pourrait être approprié d’identifier la nouvelle méthode. Bien que la suggestion d'utiliser add_compiler_

Pour ceux qui cherchent ici une version plus moderne de cmake (3.1+), la réponse la plus appropriée n'est pas d'identifier une version d'un compilateur donné mais de laisser CMAKE savoir quelles fonctionnalités doivent être disponibles.

target_compile_features(engine
    PRIVATE cxx_range_for
    )
0
Brian Bruggeman

J'active toujours c ++ 11 dans mon code en utilisant CMake de cette façon:

set(CMAKE_CXX_FLAGS "-std=c++11")

Mon compilateur est gcc (Debian 4.9.2-10) 4.9.2, mais sur mon lieu de travail, j'utilise également d'autres versions et cette approche fonctionne toujours.

EDIT (pour éviter l'écrasement des variables):

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
0
Ptaq666