在 cmake 中使用 __GLIBCXX__ 的值

Using value of __GLIBCXX__ in cmake

有很多使用 cmake 设置预处理器值的示例。我遇到了相反的问题——我想找到 __GLIBCXX__ 的值,然后根据结果有条件地执行其他 cmake 命令。

到目前为止,我一直在使用 GCC 版本作为 libstdc++ 功能的替代品,如下所示:

if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
    if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
        ....
    # other gcc versions
        ....
    endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
    # and so on
endif()

我现在遇到的问题是 libstdc++ and gcc-4.8 c++11 regex support 的一个已知问题的后果,事实上在许多设置中 clang 重用了系统 libstdc++,因此继承了相同的系统问题。在这种情况下,clang 的版本测试没有帮助,因为它与 libstdc++ 特别相关,我使用编译器版本的替代方法不再有效。

如果 clanggcc 正在使用与 gcc-4.8 一起分发的 libstdc++Boost.RegexPCRE早些时候,我能想到的最好方法是检查 __GLIBCXX__ <= 20140404,但我看不出如何让 cmake 以直接的方式进行,因为 clang 可能并不总是使用 libstdc++,例如大多数 OS X 系统。

CheckVariableExists 似乎没有帮助,我想至少有两个原因;首先,预处理器宏不是变量,其次,它不提供值,仅指示其存在。

您可以使用 CHECK_CXX_SOURCE_COMPILES 编译特定测试,当您的条件不满足时该测试失败:

INCLUDE (CheckCXXSourceCompiles)
CHECK_CXX_SOURCE_COMPILES(
"
#include <cstdio>
#ifdef __GLIBCXX__
#if __GLIBCXX__ <= 20140404
#error test failed
#endif
#endif
int main() { return 0;} 
" GLIBCXX_TEST) 

IF(NOT GLIBCXX_TEST)
MESSAGE(STATUS "__GLIBCXX__ test failed")
ENDIF()

基于 m.s. 的想法并采纳 Marc Glisse 关于 __GLIBCXX__ 不是测试此问题的可靠方法的观察,我编写了一个 CMake 模块来测试正则表达式支持的损坏实现.为了通过此测试,编译器需要以 C++11 或更高版本为目标。

要点在这里:https://gist.github.com/anonymous/7520ce6f64c63e2f8e79

示例使用:

include(CheckForRegex)
check_cxx_native_regex_works(USE_NATIVE_REGEX)
add_definitions("-DUSE_NATIVE_REGEX=${USE_NATIVE_REGEX}")

if (NOT USE_NATIVE_REGEX)
    find_package(Boost REQUIRED COMPONENTS regex)
endif()