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
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.
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_REQUIRED
OFF
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)
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
)
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")