简体   繁体   中英

add c++0x support in cmake

I have a rather large application configured in cmake. I have recently added a couple of classes that utilize C++0x functionality, and it breaks the build, since cmake is not configured to compile with C++0x support. How do I add that as an option to cmake?

您需要将标志添加到CMAKE_CXX_FLAGS

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

I use this snippet for gcc, but it is a more complicated way

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

I have the following module:

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

I use this to check if the subset of C++11 I'm using (actually this is redundant now, as I'm using a lot more), is supported by the compiler. It is easy to build this further and add more features, and add other compiler switches. Actually the only compilers I have found so far which passes this test, is gcc >= 4.6 and clang >= 3.1 if I remember correctly.

As shown in this answer , it's better to use target_compile_features to require support for the specific features that you need.

This explains/documents better what functionality your code requires, is cross-platform compatible, and will give the user a more helpful error message if the required feature is not available in their compiler.

From the manual page for this option:

 target_compile_features 

Add expected compiler features to a target.

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

Specify compiler features required when compiling a given target. If the feature is not listed in the CMAKE_C_COMPILE_FEATURES variable or CMAKE_CXX_COMPILE_FEATURES variable, then an error will be reported by CMake. If the use of the feature requires an additional compiler flag, such as -std=gnu++11 , the flag will be added automatically.

The (hopefully complete) list of features that can be tested with this macro is here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM