Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define transitive CXX_STANDARD C++11 in Cmake

Tags:

c++

c++11

cmake

I have a header only C++11 library, so I want to configure it, using CMake > 3.1, compile features seems reasonable way to do so:

target_compile_features(my_header_lib INTERFACE cxx_range_for)

But I would prefer not having to indicate individual features, but just C++11 or C++14. Then I could try to use the following:

set_property(TARGET my_target PROPERTY CXX_STANDARD 11)

The problem is that my_target cannot be INTERFACE here, it is not supported, and I cannot define it PUBLIC, so consumers (many EXEs) of my header only library will automatically have the C++11 configuration propagated from the lib.

Is there some way to define at a high level 11/14 standard, but also configure it for a header only (INTERFACE) library? I would prefer not to fall back to old manual -std=c++11.

like image 280
drodri Avatar asked Apr 16 '15 22:04

drodri


2 Answers

CMake 3.8 (released in April 2017) introduced meta-features (e.g. cxx_std_11, cxx_std_14, cxx_std_17). You can now for instance write:

target_compile_features(my_header_lib INTERFACE cxx_std_11)
like image 106
Erik Sjölund Avatar answered Oct 16 '22 17:10

Erik Sjölund


The simplest solution for now is to manually maintain lists of C++11 and C++14 features in a global variable and feed that list to target_compile_features.

set(CXX11_FEATURES
    cxx_auto_type
    cxx_constexpr
    [...]
)

set(CXX14_FEATURES
    cxx_generic_lambdas
    [...]
)

target_compile_features(my_header_lib INTERFACE ${CXX11_FEATURES} ${CXX14_FEATURES})

Arguably, it would be nice if CMake already provided those lists for you, but currently it does not.

Note that this is consistent with how the compile features mechanism currently works in CMake. The CXX_STANDARD property determines which flag is given to the compiler on the command line. Just because you request a certain standard version however does not guarantee that it will correctly compile a certain feature. The only way to ensure that a certain feature is present (and fail with a meaningful error if it's not) is by checking it through target_compile_features.

The complication here really is not due to how CMake handles things, but due to the fact that different compilers implement different subsets of the standard.

like image 39
ComicSansMS Avatar answered Oct 16 '22 19:10

ComicSansMS