如何在 Cmake 中定义传递 CXX_STANDARD C++11

How to define transitive CXX_STANDARD C++11 in Cmake

我有一个 header 只有 C++11 的库,所以我想配置它,使用 CMake > 3.1,编译功能似乎是合理的方式:

target_compile_features(my_header_lib INTERFACE cxx_range_for)

但我宁愿不必指出个别功能,而只需指出 C++11 或 C++14。然后我可以尝试使用以下内容:

set_property(TARGET my_target PROPERTY CXX_STANDARD 11)

问题是my_target在这里不能是INTERFACE,它不受支持,我不能定义它PUBLIC,所以我的header only library的消费者(很多EXE)将自动从库中传播 C++11 配置。

是否有某种方法可以在高级 11/14 标准上进行定义,而且还可以针对 header 仅 (INTERFACE) 库进行配置?我不想回到旧手册 -std=c++11.

目前最简单的解决方案是在全局变量中手动维护 C++11 和 C++14 功能列表,并将该列表提供给 target_compile_features

set(CXX11_FEATURES
    cxx_auto_type
    cxx_constexpr
    [...]
)

set(CXX14_FEATURES
    cxx_generic_lambdas
    [...]
)

target_compile_features(my_header_lib INTERFACE ${CXX11_FEATURES} ${CXX14_FEATURES})

可以说,如果 CMake 已经为您提供了这些列表,那就太好了,但目前还没有。

请注意,这与当前 CMake 中编译功能机制的工作方式一致。 CXX_STANDARD 属性 确定在命令行上为编译器提供哪个标志。然而,仅仅因为您请求某个标准版本并不能保证它会正确编译某个功能。确保某个功能存在(如果不存在则失败并出现有意义的错误)的唯一方法是通过 target_compile_features.

检查它

这里的复杂性并不是因为 CMake 处理事情的方式,而是因为不同的编译器实现了标准的不同子集。

CMake 3.8(2017 年 4 月发布)引入了元特征(例如 cxx_std_11cxx_std_14cxx_std_17)。你现在可以写:

target_compile_features(my_header_lib INTERFACE cxx_std_11)