【发布时间】:2016-12-19 10:14:14
【问题描述】:
我正在使用 CMake 开发一个项目。我的代码包含 constexpr 方法,这些方法在 Visual Studio 2015 中是允许的,但在 Visual Studio 2013 中是不允许的。
如果指定的编译器支持该功能,我如何签入CMakeLists.txt?我在 CMake 文档CMAKE_CXX_KNOWN_FEATURES 中看到过,但我不明白如何使用它。
【问题讨论】:
我正在使用 CMake 开发一个项目。我的代码包含 constexpr 方法,这些方法在 Visual Studio 2015 中是允许的,但在 Visual Studio 2013 中是不允许的。
如果指定的编译器支持该功能,我如何签入CMakeLists.txt?我在 CMake 文档CMAKE_CXX_KNOWN_FEATURES 中看到过,但我不明白如何使用它。
【问题讨论】:
您可以使用 target_compile_features 来要求 C++11(/14/17) 功能:
target_compile_features(target PRIVATE|PUBLIC|INTERFACE feature1 [feature2 ...])
feature1 是CMAKE_CXX_KNOWN_FEATURES 中列出的功能。例如,如果您想在公共 API 中使用 constexpr,您可以使用:
add_library(foo ...)
target_compile_features(foo PUBLIC cxx_constexpr)
您还应该查看WriteCompilerDetectionHeader module,它允许将功能检测为选项,并在编译器不支持的情况下为某些功能提供向后兼容性实现:
write_compiler_detection_header(
FILE foo_compiler_detection.h
PREFIX FOO
COMPILERS GNU MSVC
FEATURES cxx_constexpr cxx_nullptr
)
如果关键字constexpr可用,这里将生成一个文件foo_compiler_detection.h,并定义FOO_COMPILER_CXX_CONSTEXPR:
#include "foo_compiler_detection.h"
#if FOO_COMPILER_CXX_CONSTEXPR
// implementation with constexpr available
constexpr int bar = 0;
#else
// implementation with constexpr not available
const int bar = 0;
#endif
此外,如果当前编译器存在该功能,FOO_CONSTEXPR 将被定义并扩展为 constexpr。否则它将为空。
FOO_NULLPTR 将被定义并扩展为 nullptr 如果当前编译器存在该功能。否则它将扩展到兼容性实现(例如NULL)。
#include "foo_compiler_detection.h"
FOO_CONSTEXPR int bar = 0;
void baz(int* p = FOO_NULLPTR);
【讨论】: