如何检测C ++ 11的支持与CMake的一个编译器如何检测C ++ 11的支持与CMake的一个编

2019-05-17 15:02发布

有没有办法让如果编译器支持C ++ 11或不CMake的自动检测?

由于这将是很好的CMake的运行,该代码将无法编译,因为编译器不支持C ++ 11时通知用户。 目前,我设置了C ++ 11的标志。 但是,如果编译器不支持它的用户获取CMake的运行过程中的编译错误,而不是一个错误。

完美的将是一些作品像find_package() 。 但是,我还没有发现它提供所需的功能的任何模块或功能。

附加这将是不错的功能来检测,如果编译器需要标志std=c++0xstd=c++11

有什么可用的还是需要开发这个我自己?

下面是一些代码,我使用至今,但它仅适用于GNU'c GCC编译。 这将是很好,如果有将是一个更通用的解决方案。

if(CMAKE_COMPILER_IS_GNUCXX)
   execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
   if (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7)
        message(STATUS "C++11 activated.")
        add_definitions("-std=gnu++11")
   elseif(GCC_VERSION VERSION_GREATER 4.3 OR GCC_VERSION VERSION_EQUAL 4.3)
        message(WARNING "C++0x activated. If you get any errors update to a compiler which fully supports C++11")
        add_definitions("-std=gnu++0x")
   else ()
        message(FATAL_ERROR "C++11 needed. Therefore a gcc compiler with a version higher than 4.3 is needed.")   
   endif()
else(CMAKE_COMPILER_IS_GNUCXX)
   add_definitions("-std=c++0x") 
endif(CMAKE_COMPILER_IS_GNUCXX)

Answer 1:

如果你有CMake的版本3.1.0或更高版本,你可以检测一下C ++功能的C ++编译器支持

cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
project(foobar CXX)
message("Your C++ compiler supports these C++ features:")
foreach(i ${CMAKE_CXX_COMPILE_FEATURES})
  message("${i}")
endforeach()

但通常你不需要使用CMake的变量CMAKE_CXX_COMPILE_FEATURES在你的CMake的脚本。 相反,有两种方法如何告诉CMake的其下的C ++标准的C ++文件应该被编译,或者通过显式指定C ++标准或通过指定所需的C ++功能,让CMake的诱导C ++标准。 CMake的将确保C ++编译器被调用,有正确的命令行标志(例如-std = C ++ 11)。

1.明确指定C ++标准

你可以显式指定C ++标准,通过设置CMake的性质CXX_STANDARDCXX_STANDARD_REQUIRED您CMake的目标。

$ cat /tmp/src/CMakeLists.txt
project(foobar CXX)
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
add_executable(prog main.cc)
set_property(TARGET prog PROPERTY CXX_STANDARD 11)
set_property(TARGET prog PROPERTY CXX_STANDARD_REQUIRED ON)
$ cat /tmp/src/main.cc
int main() {
  return 0;
}
$ mkdir /tmp/build
$ cd /tmp/build
$ cmake /tmp/src
-- The CXX compiler identification is GNU 4.8.2
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/build
$ make VERBOSE=1 | grep main.cc | grep -- "-c"
/usr/bin/c++    -std=gnu++11 -o CMakeFiles/prog.dir/main.cc.o -c /tmp/src/main.cc
$

2.指定所需的C ++特征和让CMake的诱导C ++标准

你可以使用CMake的命令target_compile_features指定在您的CMake目标利用的C ++特性。 从该列表中的CMake将引起将要使用的C ++标准。 CMake的全球房地产CMAKE_CXX_KNOWN_FEATURES列出++功能,你可以选择的温度。

cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
message("Your CMake version supports these C++ features:")
get_property(known_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
foreach(i ${known_features})
  message("${i}")
endforeach()

例如,该C ++的文件名main.cc程序使用的C ++ 11特征:cxx_strong_enums,cxx_constexpr,cxx_auto_type

#include <cstdlib>

int main(int argc, char *argv[]) {
  enum class Color { Red, Orange, Yellow, Green, Blue, Violet };
  constexpr float a = 3.1415f;
  auto b = a;
  return EXIT_SUCCESS;
}

此文件的CMakeLists.txt将建立它

cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
project(foobar CXX)
add_executable(foobar main.cc)                                                                                                                                                                                                                                                     
set(needed_features
    cxx_strong_enums
    cxx_constexpr
    cxx_auto_type)
target_compile_features(foobar PRIVATE ${needed_features})


Answer 2:

在这一点上,CMake的不具有方便的形式来支持C ++ 11。 理想情况下,你会指定一个C ++ 11的项目是这样的:

project(foo CXX11)

在你开始时CMakeLists.txt 。 但CXX11项目类型不存在(还)。 在那之前,你可以使用一个两阶段的技术:

  1. 确定编译器类型和版本
  2. 相应地调整构建标志。

例如,这是我用它来支持C ++ 11锵和GCC:

# Initialize CXXFLAGS.
set(CMAKE_CXX_FLAGS                "-Wall -std=c++11")
set(CMAKE_CXX_FLAGS_DEBUG          "-O0 -g")
set(CMAKE_CXX_FLAGS_MINSIZEREL     "-Os -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE        "-O4 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")

# Compiler-specific C++11 activation.
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 ()
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
else ()
    message(FATAL_ERROR "Your C++ compiler does not support C++11.")
endif ()


Answer 3:

我发现这个CMake的脚本,号称做的正是你所需要的。 它还可以检查各个C ++ 11种功能。 我不认为这能之间做出选择std=C++0xstd=C++11虽然。



Answer 4:

在写这篇文章的时间(预GCC 4.8) ,它可能不会是检测C ++ 11米的标志,并将其添加一个好主意。 这是因为改变(至少对于GCC)的标准打破ABI兼容性 ,这会导致连接错误。

因此,使用C ++ 11标准的应明确与所述编译器设置的过程中指定的项目的初始CMake的配置 ,例如

CXX='g++ -std=c++11' cmake /path/to/source

即,使用-std的= C ++ 11应该象一个单独的编译器,它不应该在一个项目中混合或改变治疗。



Answer 5:

include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
    message(FATAL_ERROR "Compiler ${CMAKE_CXX_COMPILER} has no C++11 support.")
endif()

从http://www.guyrutenberg.com/2014/01/05/enabling-c11-c0x-in-cmake/有轻微的变化



Answer 6:

在CMake的3.1 *正确的,简单的方法来做到这一点是使用CXX_STANDARD属性给定的目标。 例如,假设使用这个简单的例子auto (名为main.cpp ):

#include <iostream>

int main() {
    auto num = 10;
    std::cout << num << std::endl;
    return 0;
}

下面CMakeLists.txt将使C ++ 11支持:

cmake_minimum_required(VERSION 3.3)
project(Hello CXX)

set(SOURCE_FILES main.cpp)
add_executable(Hello ${SOURCE_FILES})

set_property(TARGET Hello PROPERTY
    CXX_STANDARD 11
    CXX_STANDARD_REQUIRED ON
)

这将增加必要的任何标志如-std=c++11 。 需要注意的是CXX_STANDARD_REQUIRED属性将阻止标准从腐烂到一个较早的版本。


正确的,不是如,简单的方式来指定CMAKE_CXX_KNOWN_FEATURES您使用,如cxx_auto_type

cmake_minimum_required(VERSION 3.3)
project(Hello CXX)

set(SOURCE_FILES main.cpp)
add_executable(Hello ${SOURCE_FILES})
target_compile_features(Hello PRIVATE cxx_auto_type)

*我没有试过在CMake的3.1,但已经验证了它在CMake的3.3。 该3.1文档并记录这所以它应该工作。



Answer 7:

我们已经写了CMake的模块用于检测和实现C ++ 11的支持,你可以在这里找到:
https://github.com/NitroShare/CXX11-CMake-Macros

它仍然是一个工作在进步,但我们都用它为一些面向Windows / Linux的/ Mac上的Qt项目。 目前只MSVC ++,GCC,以及锵的支持。

例:

include(CXX11)

check_for_cxx11_compiler(CXX11_COMPILER)

# If a C++11 compiler is available, then set the appropriate flags
if(CXX11_COMPILER)
    enable_cxx11()
endif()


文章来源: How to detect C++11 support of a compiler with CMake
标签: c++ c++11 cmake