如何使用 CMake 检测编译器对 C++11 的支持 [英] How to detect C++11 support of a compiler with CMake

查看:129
本文介绍了如何使用 CMake 检测编译器对 C++11 的支持的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法让 CMake 自动检测编译器是否支持 C++11?

最好在 CMake 运行期间通知用户代码将无法编译,因为编译器不支持 C++11.目前我设置了 C++11 标志.但是,如果编译器不支持它,用户会在 CMake 运行期间收到编译错误而不是错误.

完美的应该是类似于 find_package() 的东西.但是,我没有找到提供所需功能的任何模块或函数.

另外,如果能够检测编译器是否需要标志 std=c++0xstd=c++11,那就太好了.>

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

以下是我目前使用的一些代码,但它仅适用于 GNU'c GCC 编译器.如果有更通用的解决方案就好了.

if(CMAKE_COMPILER_IS_GNUCXX)执行进程(命令 ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)如果(GCC_VERSION VERSION_GREATER 4.7 或 GCC_VERSION VERSION_EQUAL 4.7)消息(状态C++11 已激活.")add_definitions("-std=gnu++11")elseif(GCC_VERSION VERSION_GREATER 4.3 或 GCC_VERSION VERSION_EQUAL 4.3)消息(警告C++0x 已激活.如果出现任何错误,请更新完全支持 C++11 的编译器")add_definitions("-std=gnu++0x")别的 ()消息(FATAL_ERROR需要 C++11.因此需要版本高于 4.3 的 gcc 编译器.")万一()否则(CMAKE_COMPILER_IS_GNUCXX)add_definitions("-std=c++0x")结束(CMAKE_COMPILER_IS_GNUCXX)

解决方案

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

cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)项目(foobar CXX)message("你的 C++ 编译器支持这些 C++ 特性:")foreach(i ${CMAKE_CXX_COMPILE_FEATURES})消息(${i}")endforeach()

但通常您不需要在 CMake 脚本中使用 CMake 变量 CMAKE_CXX_COMPILE_FEATURES.相反,有两种方法可以告诉 CMake 在哪个 C++ 标准下编译你的 C++ 文件,或者通过明确指定 C++ 标准或通过指定所需的 C++ 功能并让 CMake 引入 C++ 标准.CMake 将确保使用正确的命令行标志(例如 -std=c++11)调用 C++ 编译器.

1.明确指定 C++ 标准

您可以通过设置 CMake 属性来明确指定 C++ 标准CXX_STANDARDCXX_STANDARD_REQUIRED 用于您的 CMake 目标.

$ cat/tmp/src/CMakeLists.txt项目(foobar CXX)cmake_minimum_required(版本 3.1.0 致命错误)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.ccint main() {返回0;}$ mkdir/tmp/build$ cd/tmp/build$ cmake/tmp/src-- CXX 编译器标识为 GNU 4.8.2-- 检查工作的 CXX 编译器:/usr/bin/c++-- 检查 CXX 编译器是否有效:/usr/bin/c++ -- 有效-- 检测 CXX 编译器 ABI 信息-- 检测 CXX 编译器 ABI 信息 - 完成-- 检测 CXX 编译特性-- 检测 CXX 编译特性 - 完成-- 配置完成-- 生成完成-- 构建文件已写入:/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 列出了 C++ 功能您可以从中选择.

cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)message("您的 CMake 版本支持这些 C++ 功能:")get_property(known_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)foreach(i ${known_features})消息(${i}")endforeach()

例如,这个文件名为 ma​​in.cc 的 C++ 程序利用了 C++11 的特性:cxx_strong_enumscxx_constexprcxx_auto_type

#include int main(int argc, char *argv[]) {enum class Color { Red, Orange, Yellow, Green, Blue, Violet };constexpr 浮动 a = 3.1415f;汽车 b = a;返回退出成功;}

这个 CMakeLists.txt 文件将构建它

cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)项目(foobar CXX)add_executable(foobar main.cc)设置(needed_featurescxx_strong_enumscxx_constexprcxx_auto_type)target_compile_features(foobar PRIVATE ${needed_features})

Is there a way to let CMake detect automatically if a compiler supports C++11 or not?

As it would be nice to inform the users during the CMake run that the code will not compile as the compiler does not support C++11. At the moment I set the C++11 flags. However, if a compiler does not support it the user gets compile errors instead of an error during the CMake run.

Perfect would be something that works like find_package(). However, I have not found any module or function which provides the functionality needed.

Additional it would be nice to have the feature to detect if the compiler needs the flags std=c++0x or std=c++11.

Is there something available or do I need to develop this on my own?

Below is some code I use so far, however it works only with GNU'c GCC compilers. It would be nice if there would be a more general solution.

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)

解决方案

If you have CMake version 3.1.0 or later you can detect what C++ features your C++ compiler supports

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

But normally you don't need to use the CMake variable CMAKE_CXX_COMPILE_FEATURES in your CMake scripts. Instead there are two ways of how to tell CMake under which C++ standard your C++ files should be compiled, either by specifying the C++ standard explicitly or by specifying the required C++ features and let CMake induce the C++ standard. CMake will make sure the C++ compiler is invoked with the correct command line flags (e.g. -std=c++11).

1. Specifying the C++ standard explicitly

You could specify the C++ standard explicitly, by setting the CMake properties CXX_STANDARD and CXX_STANDARD_REQUIRED for your CMake target.

$ 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. Specifying the required C++ features and let CMake induce the C++ standard

You could use the CMake command target_compile_features to specify the C++ features that are made use of in your CMake target. From this list CMake will induce the C++ standard to be used. The CMake global property CMAKE_CXX_KNOWN_FEATURES lists the C++ features you can choose from.

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

For example, this C++ program with the filename main.cc makes use of the C++11 features: 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;
}

This CMakeLists.txt file would build it

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

这篇关于如何使用 CMake 检测编译器对 C++11 的支持的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆