【问题标题】:How to request C++11 or later on a CMake-target?如何在 CMake 目标上请求 C++11 或更高版本?
【发布时间】:2019-01-16 09:09:01
【问题描述】:

(这个问题实际上是关于“或以后”的部分。)

我知道其他答案告诉我们在 cmake 中的目标/项目上激活 C++11。

我的问题实际上是我们如何表达 C++11 或更高版本。

从 CMake 3.8 开始,我们有 cxx_std_11- 功能,它在编译器 (-std=c++11) 上强制使用 C++11,它甚至支持更高的标准,甚至可能默认为 C++14 (gcc-7) 甚至 17 (gcc-8, iiuc)。

还有 CXX_STANDARD-target-property,但这不是传递性的,并且还强制使用确切的标准,而不是“或更高”的选项。

到目前为止,我发现的唯一方法是要求 cxx_range_for(或类似功能),如果至少支持 C++11,CMake 会保持编译器的默认 C++ 标准。从 CMake 3.1 开始支持此功能。

选择 C++11 或更高版本的 CMake 目标的正确方法是什么?

【问题讨论】:

  • 使用不同的标准构建项目的不同部分并不是一个好主意。
  • 如果你的源代码是 C++11,你为什么要使用更高版本的标准来编译它?请注意,较新的标准并非 100% 向后兼容。
  • 对于仅标头库,如果它也适用于更高版本,您可能不想强制依赖者使用 C++11。这是我的用例。

标签: c++ cmake


【解决方案1】:

很遗憾,在 CMake 中无法要求范围的标准。

那么唯一的方法(我过去使用过的)就是使用例如check_cxx_compiler_flag 检查 -std=c++20-std=c++17-std=c++14-std=c++11(按此顺序)并使用最高的,例如target_compile_options.

如果列出的标志都不支持,则会出错。

【讨论】:

  • 好主意,但这与平台无关。
  • @PatrickB。不幸的是没有。这适用于三大编译器中的两个(GCC 和 Clang),您可以添加对 MSVC 的检查,以类似方式检查其特定标志和标准选项。
  • 这也应该适用于自 2015 更新 3 以来的所有 MSVC 版本,因为微软当时在编译器中添加了对这些命令行开关的支持。
【解决方案2】:

正如@Some 程序员老兄指出的那样,唯一的方法是检查 C++17,然后是 C++14,然后是 C++11。查看 CMake 源代码本身提供了有趣的想法,即如何以与平台无关的方式进行操作。在这里,try_compile command 与相应的 CMAKE_CXX_STANDARD 一起使用,因此 CMake 自己决定应该使用哪个编译器标志。因此要检查 C++14:

try_compile(CMake_CXX14_WORKS
  ${CMAKE_CURRENT_BINARY_DIR}
  ${CMAKE_CURRENT_LIST_DIR}/cm_cxx14_check.cpp
  CMAKE_FLAGS -DCMAKE_CXX_STANDARD=14
  OUTPUT_VARIABLE OUTPUT
  )

其中 cm_cxx14_check.cpp 是带有main 的虚拟文件。

这是这里的关键思想,尽管完整的逻辑还会检查 CMAKE_CXX_STANDARD 是否尚未定义或者 CMake 是否知道 CMAKE_CXX_STANDARD=17 (CMake >= 3.8)。此外,CMake 仅检查 GNU 或 Clang 的最新标准,但我相信这是因为 MSVC 在非库代码中不需要它。 MSVC 一直默认启用最新的标准。

不幸的是,这也是 GNU 4.8 的一个极端案例:"The GNU 4.8 standard library's cstdio header is not aware that C++14 honors C11's removal of "gets" from stdio.h and results in an error"

【讨论】:

    猜你喜欢
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    • 2020-04-18
    • 2021-07-03
    • 1970-01-01
    • 2021-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多