【问题标题】:How do I force dependents on my INTERFACE library to use C++11 or later?如何强制我的 INTERFACE 库上的依赖项使用 C++11 或更高版本?
【发布时间】:2020-06-29 08:39:38
【问题描述】:

我正在将我的一个库拆分为一个仅包含标头的库和一个已编译的库,因此,我第一次尝试使用 CMake 来“构建”,或者更确切地说,公开一个仅标头库。

阅读 this 和 CMake 文档,我知道我需要使用 INTERFACE 库,没有源代码。但是 - 我的头文件必须使用至少 C++11 的 C++ 语言标准版本进行编译。当我实际编译某些东西时,我凑合了:

set_property(TARGET foo PROPERTY CXX_STANDARD 11)
set_property(TARGET foo PROPERTY CXX_STANDARD_REQUIRED ON)
set_property(TARGET foo PROPERTY CXX_EXTENSIONS OFF)

但那是:

  1. 对于使用仅标头库的代码而言,这并不完全符合我的要求 - 我需要说“至少 C++11”。
  2. 不能用于 INTERFACE 库。

我注意到没有set_property(... INTERFACE)。那么我应该如何强制依赖代码使用 C++11 或更高版本?

编辑:我对在依赖项中限制精确 C++ 版本选择的答案和限制“至少”的答案都感兴趣 - 如果后者有问题/困难/不可能。

【问题讨论】:

  • 我搜索了一下,我找到了this SO thread。两个答案都很有趣。但是您似乎没有一种干净的方式来指定“至少”。
  • 我会把它放在头文件static_assert(__cplusplus >= 201103L, "C++11 or later required");
  • @TedLyngmo:我想这很有用。但是 - 我希望在构建配置阶段失败,而不是在编译期间。

标签: c++ cmake build-definition build-dependencies header-only


【解决方案1】:

如果你有一个相当新版本的 cmake,你可以试试

target_compile_features(foo INTERFACE cxx_std_11)

这样可以确保每个使用 foo 的库,即

target_link_libraries(bar PRIVATE foo)

将使用 C++11 编译。例如如果bar使用源文件bar.cpp,那么bar.cpp会被cmake编译成std=c++11

【讨论】:

  • “使用 C++11” - 完全正确,或者至少?
  • 好吧,如果你指定 std=c++11 你会得到准确的 c++11 所以我会说准确:)
  • 如果您需要对功能进行一些细粒度的控制。例如,如果您想要 constexpr 支持但不想将问题修复为 c++11 或 17,您可以使用 target_compile_features(foo INTERFACE cxx_constexpr)。 CMake 将确保它受到支持,并且 bar 是在该支持下编译的。
  • ...啊,等等:CMake 文档说“cxx_std_11:编译器模式至少为 C++ 11。” !
  • 尽可能使用target_* 命令而不是set_property() 命令。您可以在此处查看 target_compile_features()。 cmake.org/cmake/help/latest/manual/…
猜你喜欢
  • 2020-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-29
  • 2014-05-09
  • 2019-12-01
  • 2019-04-18
  • 2020-09-26
相关资源
最近更新 更多