Proper way to set compiler and language standard in CMake


project(${TARGET_NAME} VERSION 1.0.0)
target_compile_features(${TARGET_NAME} PUBLIC cxx_std_14)

I get, with gcc 5.5.0 (Ubuntu 16.04):

g++  -I/MyPackage/src/MyProject -isystem /MyPackage/includes -DNDEBUG -O2 -Wall -Wextra -Wconversion -Wold-style-cast -Winline -pedantic -o CMakeFiles/MyProject.dir/source1.cpp.o -c /MyPackage/src/MyProject/source1.cpp
In file included from /usr/include/c++/5/tuple:35:0,
                 from /MyPackage/includes/ThaliaUtilities/SomeHeader.hpp:35,
                 from /MyPackage/src/ThaliaUtilities_UT/MyProject.h:21,
                 from /MyPackage/src/ThaliaUtilities_UT/MyProject.cpp:21:
/usr/include/c++/5/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
 #error This file requires compiler and library support

I indeed cannot see -std=c++14 in the command line gcc does not seem to default to C++11.

I previously set CMAKE_CXX_COMPILER before calling project but then, successive calls of cmake on a project where I change CPP_COMPILER in-between, still call the previous compiler.

To sum it up:
What is the proper way, in modern CMake, to choose the compiler (and to change it, on demand)?
Is it possible from a CMakeLists?
What is the proper way, in modern CMake, to set the language standard use?
Is it possible from a CMakeLists?


1 Like

Either using a toolchain file, using cmake -DCMAKE_${LANG}_COMPILER= on the first configure, or CC=… CXX=… cmake on the first configure.

Generally, no. A compiler change is only safe with a new, fresh build tree.

target_compile_features should do it. You can also do set(CMAKE_CXX_STANDARD 14) at the top-level (assuming your project is a “leaf”; if you have an SDK/headers installed, you may want the usage requirement semantics of target_compile_features).

Thanks for your answer.
I made further tests and indeed see that setting compiler at any other moment than at the command call leads to inconsistent cache.
My use case is to compile with differents compilers on a regular basis: the best way is so to delete the build tree before calling cmake again with a -DCMAKE_CXX_COMPILER=… for instance?
But I had also surprises with target_compile_feature and gcc 5.5 (sorry I can’t upload an example) as the requested language level was not set. When should I use target_compile_feature (with respect to project, add_library/add_executable?)
I must support xenial versions as my users may not be able to upgrade their applications.


I would make a build tree per compiler instead of starting from scratch each time.

add_library(mytarget) # or add_executable()
target_compile_features(mytarget PRIVATE cxx_std_14) # or PUBLIC if you use C++14 in headers.

CMake’s downloads do not require special permissions to install; one extracts the tarball and uses it in-place.

Hi again,

Having a build tree per compiler seems to be a good idea. I’ll look into this.

But for now, I’m utterly confused:
If I set the compiler through command line instead of “set” command in my CMakeLists, my project doesn’t link anymore with the C++ runtime (undeifned reference to all of std’s symbols).

I can’t see any reason why…

By the way, I use the “MinGW Makefiles” generator.


Hmm. Are you somehow ending up with a C compiler rather than a C++ compiler somehow? Does a simple mingw-g++ simple_main.cpp -o simple_main compilation work (if it uses the stdlib) outside of CMake?

yes, it works…
by the way, I’ve got the issue with mingw but not with “NMAKE generator”/cl

Hmm. That seems odd. Could you please file an issue with more details about your setup and a small example project?

hum, embarrassing. I’ve just found the problem: it was a “chair-keyboard interface” issue :wink:
I call CMake through a bunch of scripts and I passed the C++ compiler as gcc, not g++ while in my CMake files I did the conversion from gcc to g++…

Now everything seems to be OK.

Thanks again for your help.

Thanks for reporting back :slight_smile: .