Patrick B.
Patrick B.

Reputation: 12343

How to request C++11 or later on a CMake-target?

(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

Answers (2)

R2RT
R2RT

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

Some programmer dude
Some programmer dude

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

Related Questions