CMake 知道 C++ 20,但 g++ 9 不知道。

huangapple go评论66阅读模式
英文:

CMake knows std 20, but g++9 doesn't

问题

I have a project, which cannot be compiled by a fellow, due to an unknown call to a method from the std library.
我有一个项目,由于对标准库中的一个未知方法的调用,无法被同事编译。

I suspect that it's due to the fellow's g++ version (9.4.2) because the function was added in the std 20 standard. To test if that is the case I installed g++-9 (Version 9.5.0) and pointed the /usr/bin/g++ symbolic link to g++-9 and stumbled upon another issue (the question).
我怀疑是因为同事使用的 g++ 版本(9.4.2)导致的,因为该函数是在C++20标准中添加的。为了测试是否是这个原因,我安装了 g++-9(版本9.5.0),并将/usr/bin/g++符号链接指向g++-9,然后遇到了另一个问题(问题)。

When I run
当我运行以下命令时:

$ 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.

我得到一个错误,指出不识别C++20标准版本。

But when I try to generate the build files for a cmake project with the following line in the CMakeLists.txt:
但是当我尝试使用CMakeLists.txt中的以下行来生成CMake项目的构建文件时:

target_compile_features(${PROJECT_NAME}
    PUBLIC
        cxx_std_20
)

I get no error. But when replacing the 20 with a 23:
我没有错误。但当我将20替换为23时:

target_compile_features(${PROJECT_NAME}
    PUBLIC
        cxx_std_23
)

I get the error
我得到错误:

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.

Why is the C++20 standard unknown to g++, but known, when generating build files with cmake?
为什么C++20标准在使用g++编译时未知,但在使用CMake生成构建文件时却知道呢?

This is some sort of follow-up Question:
这是某种后续问题:

When I try to compile my project I get the error:
当我尝试编译我的项目时,我遇到错误:

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

and view was added in c++20. Can it be, that view was yet not added in c++2a?
而且view是在C++20中添加的。可能是因为view尚未在C++2a中添加?

英文:

I have a project, which cannot be compiled by a fellow, due to an unknown call to a method from the std library.
I suspect that it's due to the fellow's g++ version (9.4.2) because the function was added in the std 20 standard. To test if that is the case I installed g++-9 (Version 9.5.0) and pointed the /usr/bin/g++ symbolic link to g++-9 and stumbled upon another issue (the question).

When I run

$ 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.

I get an error stating, that the std standard version 20 is unknown.
But when I try to generate the build files for an cmake project with the following line in the CMakeLists.txt:

target_compile_features(${PROJECT_NAME}
    PUBLIC
        cxx_std_20
)

I get no error. But when replacing the 20 with a 23:

target_compile_features(${PROJECT_NAME}
    PUBLIC
        cxx_std_23
)

I get the error

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.

Why is the C++20 standard unknown to g++, but known, when generating build files with cmake?


This is some sort of follow up Question:

When I try to compile my project I get the error:

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

and view was added in c++20. Can it be, that view was jet not added in c++2a?

答案1

得分: 2

好的,以下是翻译好的部分:

  1. "Well... if your compiler is GCC 9.5.0, the reason why CMake says your compiler doesn't know about C++23 is because... it doesn't?"

    中文翻译:嗯...如果你的编译器是GCC 9.5.0,CMake说你的编译器不支持C++23的原因是因为...它确实不支持吗?

  2. "The only thing that cppreference.com's compiler support table says that GCC v9 "knows" about C++23 is "Narrowing contextual conversions in static_assert and constexpr if"

    中文翻译:cppreference.com的编译器支持表中唯一提到的GCC v9支持C++23的事项是“static_assertconstexpr if中的_窄化上下文转换_”。

  3. "And the reason why you get "_g++-9: error: unrecognized command line option ‘-std=20’; did you mean ‘-std=c2x’?" for GCC 9.5.0 is probably just because C++20 support wasn't fully implemented yet."

    中文翻译:你在GCC 9.5.0上出现"_g++-9: error: unrecognized command line option ‘-std=20’; did you mean ‘-std=c2x’?"的原因很可能是因为C++20支持尚未完全实现。

  4. "So just do what it told you to do and take what you get, accepting that not all of the C++20 features will be available in GCC 9.5.0."

    中文翻译:所以只需按照它告诉你的去做,并接受在GCC 9.5.0中不会提供所有C++20功能的事实。

  5. "Or upgrade your compiler :P"

    中文翻译:或者升级你的编译器 CMake 知道 C++ 20,但 g++ 9 不知道。

  6. "The reason why it works with CMake's target_compile_features(... cxx_std_20) is because... CMake handles it."

    中文翻译:它之所以能够使用CMake的target_compile_features(... cxx_std_20)是因为...CMake进行了处理。

英文:

Well... if your compiler is GCC 9.5.0, the reason why CMake says your compiler doesn't know about C++23 is because... it doesn't?

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

The only thing that cppreference.com's compiler support table says that GCC v9 "knows" about C++23 is "Narrowing contextual conversions in static_assert and constexpr if"

And the reason why you get "g++-9: error: unrecognized command line option ‘-std=20’; did you mean ‘-std=c2x’?" for GCC 9.5.0 is probably just because C++20 support wasn't fully implemented yet. Again, look at the compiler support table in cppreference.com. There are lots of core language features and library features for C++20 that GCC didn't implement until version 10 (some even in version 9-13 Ex. "Atomic Compare-And-Exchange with padding bits")

So just do what it told you to do and take what you get, accepting that not all of the C++20 features will be available in GCC 9.5.0.

Or upgrade you compiler CMake 知道 C++ 20,但 g++ 9 不知道。

The reason why it works with CMake's target_compile_features(... cxx_std_20) is because... CMake handles it.

See Modules/Compiler/GNU-C.cmake:

> 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()
>

and Modules/Compiler/GNU-CXX.cmake:

> 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()
>

答案2

得分: 1

The name of the option for standard C++20 up to GCC 9 is -std=c++2a. According to man gcc:
> c++2a
>
> ISO C++标准的下一个修订版本,计划于2020年发布。支持高度实验性,几乎肯定会在未来的版本中以不兼容的方式进行更改。

因此,不应期望所有功能都会在其中。

GCC有一个传统,即为尚未发布的标准或支持不完整的标准提供别名。GCC 9仅支持c++2a,而在GCC 10中,它成为了c++20的别名。

CMake可以处理这个问题。如果不确定CMake使用的标准(或任何其他选项),请查看构建目录中的flags.makebuild.ninja(取决于你使用的生成器)。

英文:

The name of the option for standard C++20 up to GCC 9 is -std=c++2a. According to man gcc:
> c++2a
>
> The next revision of the ISO C++ standard, planned for 2020. Support is highly experimental, and will almost certainly change in incompatible ways in future releases.

So not all features can be expected to be in there.

GCC has a tradition of providing aliases for the not yet released standards or those with incomplete support. GCC 9 only knows c++2a and that became an alias for c++20 with GCC 10.

CMake can handle this. When in doubt what CMake uses as standard (or any other option), take a look in the build directory in flags.make or build.ninja (depending on which generator you're using).

huangapple
  • 本文由 发表于 2023年2月16日 17:27:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/75470181.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定