我有一个基于 cmake 的小型 C++11 库,可以通过使用一些 C++14 和一些 C++17 特性来改进。
为此,我希望 CMake 测试cxx_std_14和/或cxx_std_17是否在列表CMAKE_CXX_COMPILE_FEATURES 中,如相关的 SO 问题How to detect C++11 support of a compiler with CMake 中所暗示的那样。
不过,我不太清楚如何编写此测试。我认为应该起作用的,不起作用:
list (FIND ${CMAKE_CXX_COMPILE_FEATURES} "cxx_std_14" _index)
if (${_index} GREATER -1)
message("YAY 14")
else()
message("NAY 14")
endif()
# -> CMake Error .... (list):
# list sub-command FIND requires three arguments
Run Code Online (Sandbox Code Playgroud)
(因为最小的 CMake 版本是 2.8.7 我必须使用list(FIND ...)而不是更新的、更简洁的IN_LIST)。
CMAKE_CXX_COMPILE_FEATURES 似乎是一个分号分隔的字符串,所以这个丑陋的片段有效:
if ("${CMAKE_CXX_COMPILE_FEATURES}" MATCHES "cxx_std_14")
message("YAY 14")
else()
message("NAY 14")
endif()
Run Code Online (Sandbox Code Playgroud)
当然,这不是正确的方法......任何帮助将不胜感激。
我不知道这是一个好还是坏的方法,但我通过枚举我支持的可能的编译器来做到这一点:
set(CompilerName_tmp "${CMAKE_CXX_COMPILER_ID}")
string(TOLOWER "${CompilerName_tmp}" CompilerName_tmp)
set(CompilerVersion_tmp "${CMAKE_CXX_COMPILER_VERSION}")
if(LINUX)
if("${CompilerName_tmp}" STREQUAL "gnu")
set(CompilerName_tmp "gcc")
endif()
if("${CompilerVersion_tmp}" VERSION_LESS "4.8.1")
set(Cxx11Available FALSE CACHE INTERNAL "")
else()
set(Cxx11Available TRUE CACHE INTERNAL "")
endif()
else()
message(FATAL_ERROR "Unexpected compiler: ${CMAKE_CXX_COMPILER}")
endif()
elseif(WINDOWS)
if("${CompilerName_tmp}" STREQUAL "intel")
if("${CompilerVersion_tmp}" VERSION_LESS "15.0.0")
set(Cxx11Available FALSE CACHE INTERNAL "")
else()
set(Cxx11Available TRUE CACHE INTERNAL "")
endif()
else()
message(FATAL_ERROR "Unexpected compiler: ${CMAKE_CXX_COMPILER}")
endif()
endif()
Run Code Online (Sandbox Code Playgroud)
另一种可能性是将您使用的所有 C++11 功能放在一个示例中,并尝试try_compile在配置期间对其进行编译。