2016-06-03 35 views
8

Sono nuovo al C++ e ho avuto difficoltà con la compilazione/creazione/collegamento/creazione/qualsiasi cosa, vediamo se qualcuno può darmi una mano. Ho fatto alcune ricerche e ho trovato altre persone con problemi simili, ma ho provato le loro soluzioni senza fortuna, quindi ecco:cmake non verrà compilato in C++ 11 standard

Un semplice programma C++ che utilizza funzionalità C++ 11 come inizializzazione uniforme, thread, to_string, ecc ... genera errori che "xxx" non è stato dichiarato nell'ambito. Specificamente ora mi piacerebbe usare to_string e usarlo nello spazio dei nomi std o nello specifico std::to_string crea l'errore "to_string" non è un membro di STD. Quindi, chiaramente non è la compilazione con C++ 11.

Quindi, ecco la mia 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() 
##################################### 

Come potete vedere sto giocando intorno con OpenCV su un pi lampone. Ma senza le funzioni C++ 11 il programma si compila e non esegue problemi. Ma vorrei aggiungere thread e altre chicche da C++ 11. Ho aggiunto la linea set_property(TARGET main PROPERTY CXX_STANDARD_REQUIRED 11) in base alla documentazione CMAKE:

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

e ha fatto alcuna differenza negli errori generati. L'ho fatto prima senza lo _REQUIRED e poi con esso. Ho anche provato target_compile_features(), ma CMAKE è tornato con "comando CMAKE sconosciuto".

Altri particolari: -Compiling su un Raspberry Pi 3 in esecuzione Debian Jessie -CXX compilatore GNU è 4.9.2 -CMAKE 3.0.2

+2

Mi sono reso conto che avevo solo CMAKE 3.0.2 e la documentazione che ho collegato era per CMAKE 3.1, forse non supporta quella proprietà CXX_STANDARD? Quello che ho finito per usare era "set (CMAKE_CXX_FLAGS" $ {CMAKE_CXX_FLAGS} -std = C++ 11 ")", che ha funzionato per me. Una versione successiva di CMAKE funzionava con il metodo set_property? Uno ha un vantaggio rispetto all'altro? – DrTarr

+2

CXX_STANDARD era nuovo in 3.1 https://cmake.org/cmake/help/v3.1/release/3.1.0.html#properties – drescherjm

+0

FYI parte delle tue difficoltà sta nel C++ 03 che è l'impostazione predefinita per GCC 4. x con 4.7 è il primo C++ 11 in grado. Quando hai GCC 5.x, C++ 11 sarà il default e GCC 6.x C++ 14 sarà il default. –

risposta

24

Nelle versioni CMake precedenti a 3.1, utilizziamo

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

per aggiungere opzioni di compilazione alla chiamata del compilatore come descritto nello CMake Docs.

Probabilmente non è così portatile come quello nella risposta di Alvaro, ma è più leggibile e visto che ci si trova su di voi RasPi, credo, GCC e Clang come faranno i compilatori di destinazione.

Edit: Per ragioni di completezza: Nella versione CMake 3.1 e successivi, se si vuole forzare C++ 11, sono necessari i seguenti linee:

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 

In questo modo le opzioni per tutti gli obiettivi durante la compilazione. Se si desidera controllare questo più a grana fine, vedere la risposta di Alvaro o CMake Docs di set_taget_properties(), che poi sembra qualcosa di simile:

set_target_properties(myTarget PROPERTIES 
    CXX_STANDARD 11 
    CXX_STANDARD_REQUIRED ON 
    CXX_EXTENSIONS OFF 
) 

Edit: Ma attenzione che il sostegno C++ 11 in GCC 4 non è completo e potrebbero esserci cose che si comportano diversamente dallo standard definito.

+0

C'è una struttura ancora più moderna: https://cmake.org/cmake/help/v3.1/manual/cmake-compile-features.7.html Puoi richiedere caratteristiche particolari e cmake forniranno automaticamente le bandiere per il compilatore –

+0

@IlyaPopov: Grazie per il suggerimento.Non sono sicuro se sia più moderno, però. È sicuramente più raffinato, ma è stato introdotto contemporaneamente a 'CMAKE_CXX_STANDARD' e agli amici. ... Inoltre, ho cercato di trovare una parola chiave per questo caso specifico (per usare 'to_string') ma non ho trovato uno. Mi è mancato? Vorrei aggiungere questo alla risposta, ma solo se riesco a inserire qualcosa di specifico. – Bugfinger

-2

ho sempre Enable C++ 11 nel mio codice usando CMake questo modo:

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

mio compilatore gcc è (Debian 4.9.2-10) 4.9.2, tuttavia a mio posto di lavoro ho anche utilizzare le altre versioni e questo approccio funziona sempre.

EDIT (per evitare di sovrascrivere variabile):

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

Sostituisce la variabile che l'utente potrebbe aver impostato su un valore personalizzato già nella sua shell. Se vuoi usarlo, fallo in questo modo: 'set (CMAKE_CXX_FLAGS" $ {CMAKE_CXX_FLAGS} "-std = C++ 11") '... ma in generale, preferisci un approccio più" moderno "come' add_compile_option () 'o la variabile' CXX_STANDARD'. :) – Bugfinger

4

CMake aggiungere il supporto per CXX_STANDARD e CXX_STANDARD_REQUIRED proprietà sulla versione 3.1. CXX_STANDARD: prendi uno dei valori CMAKE_CXX_STANDARD e sono 98, 11 and 14. Se si passa CXX_STANDARD 11 e il compilatore non supporta C++ 11 CXX_STANDARD diventa 98 ​​automaticamente e cmake non ti dà alcun errore se CXX_STANDARD_REQUIRED è OFF o non impostato. Se il valore impostato CXX_STANDARD_REQUIRED "ON" CXX_STANDARD diventa come una proprietà richiesta da compilare e cmake gestirlo.

in orde di utilizzare CHECK_CXX_COMPILER_FLAG si Nedd includere modulo 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) 

Se si dispone di un CMake vecchia è necessario gestire complicare e non bandiere portatili da compilatori sush come:

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

Poiché l'attuale versione cmake è 3.10, ho pensato che potrebbe essere appropriato identificare il metodo più recente. Mentre il suggerimento di usare add_compiler_

Per chi guarda qui una versione più moderna di cmake (3.1+), la risposta più appropriata non è identificare una versione di un determinato compilatore ma lasciare che CMAKE sappia quali caratteristiche devono essere a disposizione.

target_compile_features(engine 
    PRIVATE cxx_range_for 
    )