如何使用 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)
   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)

原文由 tune2fs 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.9k
2 个回答

如果您有 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 变量 CMAKE_CXX_COMPILE_FEATURES 。相反,有两种方法可以告诉 CMake 您的 C++ 文件应该在哪个 C++ 标准下编译,通过明确指定 C++ 标准或通过指定所需的 C++ 功能并让 CMake 引入 C++ 标准。 CMake 将确保使用正确的命令行标志(例如 -std=c++11)调用 C++ 编译器。

  1. 明确指定 C++ 标准

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

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

  1. 指定所需的 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("Your CMake version supports these C++ features:")
get_property(known_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
foreach(i ${known_features})
  message("${i}")
endforeach()

例如,这个文件 名为 main.cc 的 C++ 程序利用了 C++11 的特性: cxx_strong_enumscxx_constexprcxx_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})


原文由 Erik Sjölund 发布,翻译遵循 CC BY-SA 4.0 许可协议

我们编写了一个用于检测和启用 C++11 支持的 CMake 模块,您可以在此处找到:

https://github.com/NitroShare/CXX11-CMake-Macros

它仍在进行中,但我们正在将它用于许多针对 Windows/Linux/Mac 的 Qt 项目。目前仅支持 MSVC++、GCC 和 Clang。

例子:

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

原文由 Nathan Osman 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题