C++ language wrongly propagated through dependency chain

I have a library L (either a static lib or a headers only library) and an client application A.
I set the required language level for L with :
target_compile_features(L PUBLIC cxx_std_14) on a recent CMake
target_compile_options(L PUBLIC $<$<COMPILE_LANGUAGE:CXX>:-std=c++14>) on older CMake version
NB I use INTERFACE if L is headers only
for A:
target_compile_features(L PUBLIC cxx_std_17) on a recent CMake
target_compile_options(L PUBLIC $<$<COMPILE_LANGUAGE:CXX>:-std=c++17>) on older CMake version

I configure/generate/build L then A

on windows/mingw everything works as expected, gcc is called with -std=c++14 for L (if static library) and -std=C++17 for A

on Ubuntu/gcc or clang I have two std options in A build command line: -std=c++14 and -std=c++17 and the language effectively used is c++14 while I expected to have c++17

I used PUBLIC/INTERFACE for L because, if the situation would be reversed (L requiring C++17 and A requiring C++14, I’d expected cmake to chose C++17 for A also).

To make it simpler, I’d like cmake to chose the highest language version in the dependency chain. What is wrong in the way I set the language? What’s the correct way?


It already does choose the highest level. Remove your manual target_compile_options flag selection and it should work.

Hum, sorry but it’s not what I observe
I use only target_compile_features or target_compile_options according to the cmake version, not both, and I have the issue described.
for recent CMake, I also add
set_target_properties(L PROPERTIES CXX_EXTENSIONS OFF) for L
set_target_properties(A PROPERTIES CXX_EXTENSIONS OFF) for A

I precise that the library and the application are not part of the same cmake project.

I’ve got a project for L that install it.
I’ve got another one for A where I do a find_package(L) followed by target_link_libraries(A PRIVATE L::L)

Doing so L config files contains
set_target_properties(TestLib::TestLib PROPERTIES

which seems OK

But in A, I find -std=c++17 AND -std=c++14 in CXX_FLAGS on Linux only.
I have the same behaviour with cmake 3.5 and 3.19

On windows with mingw I’ve got only -std=c++17


Ah, I see I missed the note at the end of the line.

Hmm. Does this thread offer any insight here? Basically, is CMAKE_CXX_STANDARD being set anywhere?

Actually I had already read the thread before posting and nope, no CMAKE_CXX_STANDARD.
The closest I can find is set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT "14")
in a CMakeCXXCompiler.cmake file.

Hmm. A small example that demonstrates the problem would be appreciated then.


It seems I have rooted down the issue to cmake version.

with CMake 3.5 (a version that I must kept compliant with), language is set with target_compile_options(L PUBLIC $<$<COMPILE_LANGUAGE:CXX>:-std=c++14>)
target_compile_options(A PUBLIC $<$<COMPILE_LANGUAGE:CXX>:-std=c++17>)

my issue with CMake 3.19 was that I forgot to rebuild also L with 3.19 and L package was propagating L target_compile_options.

So the issues narrows down to how properly propagate language on CMake version that does not support target_compile_features(… cxx_std_17|cxx_std_14|…)?


Alas, I think the answer is “update your CMake”. CMake 3.5 just isn’t going to magically support standards or compilers that were released after it (though we do try to make that work as well as possible, it’s just not bullet-proof).