CMake 知道 std 20,但 g++9 不知道

问题描述 投票:0回答:2

我有一个项目,由于对 std 库中的方法的未知调用,无法由其他人编译。
我怀疑这是由于该家伙的 g++ 版本(9.4.2)所致,因为该函数是在 std 20 标准中添加的。为了测试情况是否如此,我安装了 g++-9(版本 9.5.0)并将

/usr/bin/g++
符号链接指向 g++-9,并偶然发现了另一个问题(问题)。

当我跑步时

$ g++-9 -std=c++20
g++-9: error: unrecognized command line option ‘-std=20’; did you mean ‘-std=c2x’?
g++-9: fatal error: no input files
compilation terminated.

我收到一条错误消息,指出 std 标准版本 20 未知。
但是当我尝试在

CMakeLists.txt
:

中使用以下行生成 cmake 项目的构建文件时
target_compile_features(${PROJECT_NAME}
    PUBLIC
        cxx_std_20
)

我没有收到任何错误。但是当用 23 替换 20 时:

target_compile_features(${PROJECT_NAME}
    PUBLIC
        cxx_std_23
)

我收到错误

CMake Error at CMakeLists.txt:74 (target_compile_features):
  target_compile_features The compiler feature "cxx_std_23" is not known to
  CXX compiler

  "GNU"

  version 9.5.0.

为什么 C++20 标准对于 g++ 来说是未知的,但在使用 cmake 生成构建文件时却是已知的?


这是某种后续问题:

当我尝试编译我的项目时,出现错误:

error: ‘std::stringstream’ {aka ‘class std::__cxx11::basic_stringstream<char>’} has no member named ‘view’

view 是在 c++20 中添加的。难道,那个view是jet的,c++2a中没有添加吗?

cmake g++ c++-standard-library
2个回答
2
投票

好吧...如果您的编译器是 GCC 9.5.0,那么 CMake 说您的编译器不了解 C++23 的原因是...它不了解?

https://en.cppreference.com/w/cpp/compiler_support

cppreference.com 的编译器支持表表示 GCC v9 “了解”C++23 的唯一内容是“缩小 static_assert

constexpr if
 中的上下文转换”

GCC 9.5.0 出现“

g++-9: error: unrecognized command line option '-std=20'; did youmean '-std=c2x'?”的原因可能只是因为 C++ 20 支持尚未完全实施。再次查看 cppreference.com 中的编译器支持表。有许多 C++20 的核心语言功能和库功能,GCC 直到版本 10 才实现(有些甚至在版本 9-13 中,例如“带有填充位的原子比较和交换”)

所以,按照它告诉你的去做,接受你得到的,接受并非所有 C++20 功能都在 GCC 9.5.0 中可用的事实。

或者升级你的编译器:P

它与 CMake 的

target_compile_features(... cxx_std_20)

配合使用的原因是... CMake 处理它。

参见

模块/编译器/GNU-C.cmake

if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 9.1) set(CMAKE_C23_STANDARD_COMPILE_OPTION "-std=c2x") set(CMAKE_C23_EXTENSION_COMPILE_OPTION "-std=gnu2x") endif()

模块/编译器/GNU-CXX.cmake:

elseif(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0) set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std=c++2a") set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std=gnu++2a") endif()

    

1
投票
标准 C++20 到 GCC 9 的选项名称是

-std=c++2a

。根据
man gcc

c++2a

ISO C++ 标准的下一个修订版,计划于 2020 年进行。支持是高度实验性的,并且几乎肯定会在未来版本中以不兼容的方式发生变化。

所以并不是所有的功能都在那里。

GCC 有为尚未发布的标准或支持不完整的标准提供别名的传统。 GCC 9 只知道

c++2a

,并且在 GCC 10 中成为 
c++20
 的别名。

CMake 可以处理这个问题。当不确定 CMake 使用什么作为标准(或任何其他选项)时,请查看

flags.make

build.ninja
 中的构建目录(取决于您使用的生成器)。

© www.soinside.com 2019 - 2024. All rights reserved.