【问题标题】:Detect supported C++ standards with CMake使用 CMake 检测支持的 C++ 标准
【发布时间】:2020-11-04 17:37:57
【问题描述】:

我有一个基于 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

(因为最低 CMake 版本是 2.8.7,我必须使用 list(FIND ...) 而不是更新、更简洁的 IN_LIST)。

CMAKE_CXX_COMPILE_FEATURES 似乎是一个分号分隔的字符串,所以这个丑陋的 sn-p 有效:

if ("${CMAKE_CXX_COMPILE_FEATURES}" MATCHES "cxx_std_14")
    message("YAY 14")
else()
    message("NAY 14")
endif()

当然,这不是正确的做法...任何帮助将不胜感激。

【问题讨论】:

  • 如果是,难道你不想迎合目标系统的编译器而不是库构建系统的编译器吗?例如为什么要使用 CMake 而不是 #ifdef if __cplusplus > 201402L 等?
  • list 命令接受列表名称,而不是其内容。正确用法是:list(FIND CMAKE_CXX_COMPILE_FEATURES "cxx_str_14" _index).
  • @einpoklum 据我了解,__cplusplus 对于检测 C++14 或 C++17 而言(跨平台和编译器)并不确定。
  • @Tsyvarev Aah... 确实如此。
  • @mcmayer:你错了……这个宏is an official part of the standard;如果编译器不提供它,这意味着它不可靠地支持标准。无数的库(可能包括标准库)都依赖它。

标签: c++ cmake


【解决方案1】:

我不知道这是好是坏,但我通过列举我支持的可能编译器来做到这一点:

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

另一种可能性是将你使用的所有 C++11 特性放在一个示例中,并在配置过程中尝试使用 try_compile 编译它。

【讨论】:

    猜你喜欢
    • 2012-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-24
    相关资源
    最近更新 更多