2016-06-03 9 views
8

Jestem nowicjuszem w C++ i zmagałem się z kompilacją/tworzeniem/łączeniem/budowaniem/cokolwiek, zobaczmy, czy ktoś może mi pomóc. Zrobiłem kilka wyszukiwań i znalazłem inne osoby z podobnymi problemami, ale próbowałem ich rozwiązań bez powodzenia, więc oto:cmake nie skompiluje się do standardu C++ 11

Prosty program w C++, który wykorzystuje funkcjonalność C++ 11, takie jak jednolita inicjalizacja, wątki, to_string, itp ... generuje błędy, które nie zostały zadeklarowane jako "xxx" w zakresie. W tej chwili chciałbym użyć to_string, a używanie go w przestrzeni nazw std lub konkretnie std::to_string tworzy błąd "to_string" nie jest członkiem STD. Widać więc, że nie jest to kompilacja z C++ 11.

więc oto mój make file:

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

Jak widać jestem zabawy z OpenCV na pi malinowym. Ale bez funkcji C++ 11 program kompiluje i nie uruchamia żadnych problemów. Ale chciałbym dodać wątki i inne gadżety z C++ 11. I dodaje linię set_property(TARGET main PROPERTY CXX_STANDARD_REQUIRED 11) zgodnie z dokumentacją CUpewnij:

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

I nie ma różnicy w generowanych błędów. Zrobiłem to najpierw bez _REQUIRED, a następnie z nim. Próbowałem też target_compile_features() zamiast tego, ale CMAKE powrócił z "nieznanym poleceniem CMAKE".

Inne szczegóły: -Compiling na Raspberry Pi 3 systemu Ubuntu Jessie -CXX kompilator GNU 4.9.2 -CMAKE 3.0.2

+2

Zdałem sobie sprawę, że mam tylko CMAKE 3.0.2, a dokumentacja, którą połączyłem, dotyczy CMAKE 3.1, może nie obsługuje tej właściwości CXX_STANDARD? To, co ostatecznie wykorzystałem, to "set (CMAKE_CXX_FLAGS" $ {CMAKE_CXX_FLAGS} -std = C++ 11 ")", który zadziałał u mnie. Czy późniejsza wersja CMAKE pracowała z metodą set_property? Czy ma się przewagę nad drugą? – DrTarr

+2

CXX_STANDARD był nowy w wersji 3.1 https://cmake.org/cmake/help/v3.1/release/3.1.0.html#properties – drescherjm

+0

Część twoich problemów związana jest z C++ 03, która jest domyślna dla GCC 4. x z 4.7 jest pierwszym zdolnym do C++ 11. Kiedy masz GCC 5.x, C++ 11 będzie domyślnym, a GCC 6.x C++ 14 będzie domyślnym. –

Odpowiedz

24

W wersjach CMake wcześniej niż 3.1 używamy

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

, aby dodać opcje kompilacji do wywołania kompilatora, jak opisano w CMake Docs.

Prawdopodobnie nie jest tak przenośny jak ten w odpowiedzi Alvaro, ale jest bardziej czytelny i skoro jesteś na twoim komputerze, RasPi, jak sądzę, zrobią to GCC i Clang jako kompilatory docelowe.

Edit: Dla kompletności: w wersji CMake 3.1 i nowsze, jeśli chcesz wymusić C++ 11, potrzebne są następujące linie:

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 

Pozwala opcje dla wszystkich celów podczas kompilacji. Jeśli chcesz sterować tym bardziej drobnoziarnista, patrz odpowiedź Alvaro lub CUpewnij Docs set_taget_properties(), które następnie wyglądać tak:

set_target_properties(myTarget PROPERTIES 
    CXX_STANDARD 11 
    CXX_STANDARD_REQUIRED ON 
    CXX_EXTENSIONS OFF 
) 

Edit: ale uwaga, C++ 11 wsparcie w GCC 4 nie jest kompletny i mogą istnieć rzeczy, które zachowują się inaczej niż określony standard.

+0

Istnieje jeszcze bardziej nowoczesny obiekt: https://cmake.org/cmake/help/v3.1/manual/cmake-compile-features.7.html Możesz poprosić szczególne funkcje i cmake automatycznie dostarczy flagi dla twojego kompilatora –

+0

@IlaaPopov: Dzięki za podpowiedź.Nie jestem pewien, czy jest bardziej nowoczesny. Jest na pewno bardziej drobnoziarnisty, ale został wprowadzony jednocześnie z "CMAKE_CXX_STANDARD" i przyjaciółmi. ... Próbowałem również znaleźć słowo kluczowe funkcji dla tego konkretnego przypadku (dla używania 'to_string'), ale nie mogłem go znaleźć. Czy tęskniłem za tym? Chciałbym dodać to do odpowiedzi, ale tylko wtedy, gdybym mógł dodać coś konkretnego. – Bugfinger

-2

zawsze pozwalają C++ 11 w moim kodu za pomocą CMake ten sposób:

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

Mój kompilator gcc (Debian 4.9.2-10) 4.9.2, jednak w moim miejscu pracy Używam również inne wersje i podejście to zawsze działa.

EDIT (aby uniknąć zmienną nadpisywanie):

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

To przesłoni zmienną, którą użytkownik mógł ustawić na jakąś niestandardową wartość już w swojej powłoce. Jeśli chcesz go użyć, zrób to w ten sposób: 'set (CMAKE_CXX_FLAGS" $ {CMAKE_CXX_FLAGS} "-std = C++ 11") '... ale ogólnie rzecz biorąc, preferuj bardziej" nowoczesne "podejście, takie jak' add_compile_option () 'lub zmienna' CXX_STANDARD'. :) – Bugfinger

4

CUpewnij dodać wsparcie dla CXX_STANDARD i CXX_STANDARD_REQUIRED właściwości na wersji 3.1. CXX_STANDARD: Podaj jedną z wartości CMAKE_CXX_STANDARD i są one 98, 11 and 14. Jeśli przekażemy CXX_STANDARD 11, a kompilator nie będzie obsługiwał C++ 11 CXX_STANDARD stanie się automatycznie 98 i cmake nie daje żadnego błędu , jeśli CXX_STANDARD_REQUIRED jest OFF lub unset. Jeśli ustawiona wartość CXX_STANDARD_REQUIRED "ON" CXX_STANDARD staje się wymaganą właściwością do budowania i cmake obsługi tego.

W Orde korzystania CHECK_CXX_COMPILER_FLAG ty nedd zawierać moduł 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) 

Jeśli masz starą cmake trzeba obsłużyć komplikują i nie przenośne flagi z kompilatorów Sush jak:

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

Ponieważ obecna wersja cmake wynosi 3.10, pomyślałem, że może być właściwe zidentyfikowanie nowszej metody. Podczas gdy sugestia użycia add_compiler_

Dla każdego, kto szuka tutaj bardziej nowoczesnej wersji cmake (3.1+), najbardziej odpowiednią odpowiedzią nie jest identyfikacja wersji danego kompilatora, ale pozwolić CMAKE wiedzieć, jakie funkcje muszą być dostępny.

target_compile_features(engine 
    PRIVATE cxx_range_for 
    ) 
Powiązane problemy