Reputation: 12343
(This question is really about the "or later"-part.)
I'm a aware of the other answers which are telling us out to activate C++11 on a target/project in cmake.
My question is really how do we express C++11 or later.
As of CMake 3.8 we have the cxx_std_11
-feature which forces C++11 on compilers (-std=c++11
) which even support later standards and may even default to C++14 (gcc-7) or even 17 (gcc-8, iiuc).
There is also the CXX_STANDARD-target-property, but this is not transitive and also force the exact standard and not the "or later"-option.
The only way I found until now is to require cxx_range_for
(or a similar feature) which makes CMake keep the default C++-standard of the compiler if at least C++11 is supported. This is supported as of CMake 3.1.
What is the correct way to select C++11 or later of a CMake-target?
Upvotes: 5
Views: 1158
Reputation: 2146
As @Some programmer dude pointed out, only way to do so is to check for C++17, then C++14 then C++11. Looking into CMake sources itself gives interesting idea how to do it in platform-agnostic way. In here try_compile
command is used with corresponding CMAKE_CXX_STANDARD passed, so CMake itself determines which compiler flag should be used. Thus to check for 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
)
where cm_cxx14_check.cpp is dummy file with main
.
This is key idea here, although full logic also checks if CMAKE_CXX_STANDARD
wasn't already defined or if CMake knows CMAKE_CXX_STANDARD=17
(CMake >= 3.8). Also, CMake checks for newest standard only for GNU or Clang, but I believe it is because it is not needed in MSVC in non-library code. MSVC has always enabled the newest standard by default.
Unfortunately, here is some also a corner case with 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"
Upvotes: 0
Reputation: 409166
Unfortunately there's no way to ask for a range of standards in CMake.
Then only way (that I have used in the past) is to use e.g. check_cxx_compiler_flag
to check for -std=c++20
, -std=c++17
, -std=c++14
and -std=c++11
(in that order) and use the highest with e.g. target_compile_options
.
If none of the flags listed is supported, then error out.
Upvotes: 1