Reputation: 121
I'm having some issues with setting the C++ standard for my project built with CMake. The code heavily uses C++11 features, so up to now I was doing:
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
Now, since recent GCC versions use C++14 by default, I end up having to link with libraries built with C++14 as public requirement, and there is a conflict when trying to build using strictly C++11.
So, the goal is to require at least the C++11 standard, but using the default compiler version if it is more recent.
I've tried with
target_compile_features(myLib PUBLIC cxx_std_11)
but CMake ends up adding the -std=c++11
flag, which is confusing because the documentation explictly says
CMake will ensure the compiler is invoked in a mode that is aware of C++ 11 (or above), adding flags such as -std=gnu++11 if necessary
I've also tried using the CMAKE_CXX_STANDARD_COMPUTED_DEFAULT
internal variable, but that is cumbersome since "98"
is greater than "11"
.
It is certainly possible to get it working using that variable or using the check_cxx_compiler_flag()
function, and testing the different cases, but I was hoping that there would be a simpler way to achieve this in a day and age where new standards arrive every three years...
Upvotes: 6
Views: 1594
Reputation: 805
I know this is an old question, but anyways: You are on the right path, just use target_compile_features
for the libraries you declare in your CMakeLists projects. There should be no problem linking a c++14 library with a c++11 library if you are using the same GCC version (it doesn't matter what -std=... do you put on each library).
So, if you have libA, libB and libC and you can just do this:
target_compile_features(libA PUBLIC cxx_std_11)
target_compile_features(libB PUBLIC cxx_std_14)
target_compile_features(libC PUBLIC cxx_std_17)
If for some reason the compiler version needed to be different, then I guess you should be able to link them if you can build shared libraries instead of static libraries.
Further clarification regarding cxx extensions and standard: If extensions want to be avoided (ie compiling with c++11 instead of gnu++11) one could set CMAKE_CXX_EXTENSIONS OFF
set(CMAKE_CXX_EXTENSIONS OFF)
Default behavior is to have CXX extensions enabled. You need to set this before the target is created.
Simple example without extensions allowed:
cmake_minimum_required(VERSION 3.16)
project(test-poc)
set(CMAKE_CXX_EXTENSIONS OFF)
add_executable(main main.cpp)
target_compile_features(main PRIVATE cxx_std_17)
we add CMAKE_CXX_EXTENSIONS OFF before creating the target, so CMake will choose -std=c++17 instead of -std=gnu++17. If we remove that line, CMake will chose -std=gnu++17
See: https://cmake.org/cmake/help/latest/prop_tgt/CXX_EXTENSIONS.html#prop_tgt:CXX_EXTENSIONS
Upvotes: 5