我确实读过以下问题:How to detect C++11 support in CMake。它基本上告诉我,如果某个编译器不支持您在代码中使用的功能,则当您希望生成失败时,CMake对C ++功能的检测的支持非常复杂,但是当您希望在生成时对此无反应时对此做出反应时,CMake的支持将非常有限失败。
我想做的不是失败,而是如果某些功能不可用,则定义一组不同的源文件,以便在需要时允许编译旧的c ++ 03代码,并在可能的情况下使用较新的c ++ 11-...。像这样的东西会很棒:
set(TARGET MyTarget)
if(CPP_STANDARD_VERSION GREATER_EQUAL 11)
set(SOURCE myModernFile.cpp)
else()
set(SOURCE myLegacyFile.cpp)
endif()
add_executable(${TARGET} ${SOURCE })
if(CPP_STANDARD_VERSION GREATER_EQUAL 11)
# Here failing would be fine if lambdas are not supported!
target_compile_features(${TARGET} PRIVATE cxx_lambdas)
endif()
按照链接的问题中的建议使用此方法时:
foreach(i ${CMAKE_CXX_COMPILE_FEATURES})
message("${i}")
endforeach()
例如使用带有CMake 3.13.2的Visual Studio 2013时,我得到以下输出:
cxx_std_98
cxx_std_11
cxx_std_14
cxx_std_17
cxx_std_20
cxx_alias_templates
cxx_auto_type
cxx_contextual_conversions
cxx_decltype
cxx_default_function_template_args
cxx_defaulted_functions
cxx_delegating_constructors
cxx_enum_forward_declarations
cxx_explicit_conversions
cxx_extended_friend_declarations
cxx_extern_templates
cxx_final
cxx_generalized_initializers
cxx_lambdas
cxx_local_type_template_args
cxx_long_long_type
cxx_nullptr
cxx_override
cxx_range_for
cxx_raw_string_literals
cxx_right_angle_brackets
cxx_rvalue_references
cxx_static_assert
cxx_strong_enums
cxx_template_template_parameters
cxx_trailing_return_types
cxx_uniform_initialization
cxx_variadic_macros
cxx_variadic_templates
对我来说,该列表对于特定功能有意义,但是具有受支持的C ++标准的常规功能显然不正确,因为VS 2013不支持C ++ 20。我想念什么吗?
现在,我最终获得了与链接问题中描述的方法大致相同的方法:我手动检查了各种编译器版本,然后根据其设置了我的 CPP_STANDARD_VERSION 属性,但这看起来非常对我来说很脆弱。真的没有其他方法吗?