2012-10-03 10 views
11

Mam dość dużą aplikację skonfigurowaną w cmake. Niedawno dodałem kilka klas, które wykorzystują funkcjonalność C++ 0x, i łamią kompilację, ponieważ cmake nie jest skonfigurowany do kompilacji z obsługą C++ 0x. Jak mogę dodać tę opcję jako opcję cmake?dodaj obsługę C++ 0x w cmake

+1

Jeśli używasz nowszego kompilatora, powinieneś użyć '-std = C++ 11'. To już nie jest szkic. –

Odpowiedz

9

Trzeba dodać flagę CMAKE_CXX_FLAGS:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") 
7

Używam tego urywek dla gcc, ale jest to bardziej skomplikowany sposób

if(CMAKE_COMPILER_IS_GNUCXX) 
    SET(ENABLE_CXX11 "-std=c++11") 

    EXECUTE_PROCESS(COMMAND "${CMAKE_CXX_COMPILER} -dumpversion" OUTPUT_VARIABLE GCC_VERSION) 
    if (GCC_VERSION VERSION_LESS 4.7) 
     SET(ENABLE_CXX11 "-std=c++0x") 
    endif() 

    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ENABLE_CXX11}") 
endif() 
0

Mam następujący moduł:

$ cat FindCXX11.cmake 
# - Finds if the compiler has C++11 support 
# This module can be used to detect compiler flags for using C++11, and checks 
# a small subset of the language. 
# 
# The following variables are set: 
# CXX11_FLAGS - flags to add to the CXX compiler for C++11 support 
# CXX11_FOUND - true if the compiler supports C++11 
# 
# TODO: When compilers starts implementing the whole C++11, check the full set 

include(CheckCXXSourceCompiles) 
include(FindPackageHandleStandardArgs) 

set(CXX11_FLAG_CANDIDATES 
    #Gnu and Intel Linux 
    "-std=c++0x" 
    #Microsoft Visual Studio, and everything that automatically accepts C++11 
    " " 
    #Intel windows 
    "/Qstd=c++0x" 
    ) 

set(CXX11_TEST_SOURCE 
" 
class Matrix 
{ 
public: 
    Matrix(int a, int b, int c, int d) 
     : data {a, b, c, d} 
    {} 

private: 
    int data[4]; 
}; 

int main() 
{ 
    int n[] {4,7,6,1,2}; 
    for (auto i : n) 
     Matrix mat (3,5,1,2); 
    return 0; 
} 
") 

foreach(FLAG ${CXX11_FLAG_CANDIDATES}) 
    set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") 
    set(CMAKE_REQUIRED_FLAGS "${FLAG}") 
    unset(CXX11_FLAG_DETECTED CACHE) 
    message(STATUS "Try C++11 flag = [${FLAG}]") 
    check_cxx_source_compiles("${CXX11_TEST_SOURCE}" CXX11_FLAG_DETECTED) 
    set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") 
    if(CXX11_FLAG_DETECTED) 
     set(CXX11_FLAGS_INTERNAL "${FLAG}") 
     break() 
    endif(CXX11_FLAG_DETECTED) 
endforeach(FLAG ${CXX11_FLAG_CANDIDATES}) 

set(CXX11_FLAGS "${CXX11_FLAGS_INTERNAL}") 

find_package_handle_standard_args(CXX11 DEFAULT_MSG CXX11_FLAGS) 
mark_as_advanced(CXX11_FLAGS) 

Używam tego do sprawdzenia, czy podzbiór C++ 11 używam (obecnie jest to zbyteczne, ponieważ jestem śpiewaj dużo więcej), jest obsługiwany przez kompilator. Łatwo to zbudować i dodać więcej funkcji, i dodać inne przełączniki kompilatora. Właściwie to jedynymi kompilatorami, które znalazłem do tej pory, które zdały ten test, jest gcc> = 4.6 i clang> = 3.1, jeśli dobrze pamiętam.

0

Jak pokazano w artykule this answer, lepiej jest użyć target_compile_features, aby wymagać obsługi określonych funkcji, których potrzebujesz.

To wyjaśnia/dokumentuje, jakie funkcje wymaga twój kod, jest kompatybilne z wieloma platformami i da użytkownikowi bardziej przydatny komunikat o błędzie, jeśli wymagana funkcja nie jest dostępna w ich kompilatorze.

Z manual page dla tej opcji:

target_compile_features 

Add spodziewane cechy kompilator cel.

target_compile_features(<target> <PRIVATE|PUBLIC|INTERFACE> <feature> [...]) 

Określa funkcje kompilatora wymagane podczas kompilowania danego celu. Jeśli funkcja nie jest wymieniona w zmiennej CMAKE_C_COMPILE_FEATURES lub CMAKE_CXX_COMPILE_FEATURES, wówczas zostanie zgłoszony błąd przez CMake. Jeśli użycie funkcji wymaga dodatkowej flagi kompilatora, , takiej jak -std=gnu++11, flaga zostanie dodana automatycznie.

Lista funkcji, które można przetestować za pomocą tego makra, to: (here).