c++cmakec++20

CMAKE_CXX_STANDARD vs target_compile_features?


I'm itching to upgrade our project to C++20. My CMakeLists.txt files generally say

set (CMAKE_CXX_STANDARD 17)
set (CMAKE_CXX_STANDARD_REQUIRED ON)

but I get the sense that's not the Right Way to do it. What is the Right Way? Is it this?:

target_compile_features(Foo PUBLIC cxx_std_20)

where Foo is the name of my target (and same for every target?) If I do that, do I the remove all the set (CMAKE_CXX_STANDARD*) lines everywhere?

Along the same lines, If I have

target_compile_features(Foo PUBLIC cxx_std_20)
target_compile_features(Bar PUBLIC cxx_std_17)
target_link_libraries(Bar PUBLIC Foo)

does that mean that when it goes to build Bar it will note that it needs to include headers from Foo and Foo needs cxx_std_20 and cxx_std_20 includes cxx_std_17 and so Bar will be built with C++20?


Solution

  • The newer alternative is definitely

    target_compile_features(Foo PUBLIC cxx_std_20)
    

    And with this you can and should remove the old set(CMAKE_CXX_STANDARD*).

    However the new version has an issue if you also want to disable compiler extensions with set(CMAKE_CXX_EXTENSIONS OFF). Its not possible with the new syntax as far as I know and combining both of them does not work either.

    And the second part of your question: Yes, cmake will recognize the dependencies and put the compiler in c++-20 mode whenever necessary.