it-swarm.com.de

cmake wird nicht nach C++ 11 standardisiert

Ich bin neu in C++ und habe mit dem Kompilieren/Erstellen/Verknüpfen/Bauen/Was auch immer zu kämpfen gehabt. Mal sehen, ob mir jemand helfen kann. Ich habe einige Suchen durchgeführt und andere Leute mit ähnlichen Problemen gefunden, aber ich habe ihre Lösungen ohne Erfolg ausprobiert.

Ein einfaches C++ - Programm, das C++ 11-Funktionen verwendet, z. B. einheitliche Initialisierung, Threads, to_string usw., generiert Fehler, die "xxx" nicht im Gültigkeitsbereich deklariert wurden. Speziell jetzt möchte ich to_string verwenden, und es im std-Namespace verwenden, oder std::to_string erzeugt den Fehler "to_string" ist kein Mitglied von STD. Es ist also eindeutig nicht mit C++ 11 kompiliert.

Also hier ist meine Make-Datei:

#####################################
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()
#####################################

Wie Sie sehen, spiele ich mit OpenCV auf einem Raspberry Pi. Ohne die C++ 11-Funktionen kompiliert das Programm jedoch und führt keine Probleme aus. Ich möchte aber Threads und andere Goodies aus C++ 11 hinzufügen. Ich habe die Zeile set_property(TARGET main PROPERTY CXX_STANDARD_REQUIRED 11) gemäß der CMAKE-Dokumentation hinzugefügt:

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

Und es machte keinen Unterschied in den erzeugten Fehlern. Ich habe es zuerst ohne den _REQUIRED und dann damit gemacht. Ich habe auch stattdessen target_compile_features() ausprobiert, aber CMAKE gab mit "unbekanntem CMAKE-Befehl" zurück.

Weitere Details: - Compilieren auf einem Raspberry Pi 3, auf dem debian jessie ausgeführt wird - CXX-Compiler ist GNU 4.9.2 - CMAKE 3.0.2

8
DrTarr

In CMake-Versionen vor 3.1 verwenden wir

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

um Compile-Optionen zum Compiler-Aufruf hinzuzufügen, wie in CMake Docs beschrieben.

Das ist wahrscheinlich nicht so tragbar wie das in Alvaro's Antwort, aber es ist lesbarer und da Sie auf RasPi sind, denke ich, werden GCC und Clang als Zielcompiler dies tun.

Edit: Der Vollständigkeit halber: In CMake-Version 3.1 und neuer benötigen Sie folgende Zeilen, wenn Sie C++ 11 erzwingen möchten:

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

Dies ermöglicht die Optionen für alle Ziele während des Kompilierens. Wenn Sie dies genauer steuern möchten, lesen Sie die Antwort von Alvaro oder die CMake Docs von set_taget_properties(), die dann etwa wie folgt aussieht:

set_target_properties(myTarget PROPERTIES
    CXX_STANDARD 11
    CXX_STANDARD_REQUIRED ON
    CXX_EXTENSIONS OFF
)

Edit: Beachten Sie jedoch, dass die Unterstützung von C++ 11 in GCC 4 nicht vollständig ist und dass sich möglicherweise Dinge unterscheiden, die sich vom definierten Standard unterscheiden.

30
Bugfinger

Fügen Sie Unterstützung für CXX_STANDARD und CXX_STANDARD_REQUIRED-Eigenschaften in Version 3.1 hinzu. _.CXX_STANDARD: Nehmen Sie einen der CMAKE_CXX_STANDARD-Werte und diese sind 98, 11 and 14____. Wenn Sie CXX_STANDARD 11 übergeben und Ihr Compiler nicht unterstützt, wird c ++ 11 CXX_STANDARD 98 automatisch und cmake geben Ihnen keine Fehlermeldung, wenn CXX_STANDARD_REQUIREDOFF oder unset ..__ ist. Wenn Ihr CXX_STANDARD_REQUIRED "ON" CXX_STANDARD-spezifischer Wert zu einer bestimmten Eigenschaft wird, müssen Sie diese Eigenschaft erstellen.

Um CHECK_CXX_COMPILER_FLAG verwenden zu können, müssen Sie das Modul CheckCXXCompilerFlag verwenden:

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)

Wenn Sie einen alten cmake haben, benötigen Sie komplizierte und nicht tragbare Flags Von Compilern sush als:

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

Da das aktuelle cmake-Release 3.10 ist, hielt ich es für angebracht, die neuere Methode zu identifizieren. Während der Vorschlag zur Verwendung von add_compiler_

Für jeden, der sich eine modernere Version von cmake (3.1+) ansieht, ist es am besten, eine Version eines bestimmten Compilers nicht zu identifizieren, sondern CMAKE wissen zu lassen, welche Funktionen verfügbar sein müssen.

target_compile_features(engine
    PRIVATE cxx_range_for
    )
0
Brian Bruggeman

Ich aktiviere C++ 11 in meinem Code immer mit CMake auf diese Weise:

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

Mein Compiler ist gcc (Debian 4.9.2-10) 4.9.2, aber an meinem Arbeitsplatz verwende ich auch andere Versionen, und dieser Ansatz funktioniert immer.

EDIT (um das Überschreiben von Variablen zu vermeiden):

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