# Proper way to set compiler and language standard in CMake

**URL:** https://discourse.cmake.org/t/proper-way-to-set-compiler-and-language-standard-in-cmake/2756
**Category:** Usage
**Created:** [February 12, 2021, 4:00pm UTC](https://discourse.cmake.org/t/proper-way-to-set-compiler-and-language-standard-in-cmake/2756 "2021-02-12T16:00:27Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![adaldev](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/9dc877/32.png) [@adaldev](https://discourse.cmake.org/u/adaldev)
#### Post date: [February 12, 2021, 4:00pm UTC](https://discourse.cmake.org/t/proper-way-to-set-compiler-and-language-standard-in-cmake/2756/1 "2021-02-12T16:00:27Z")

</div>

Hi,

```auto
...
project(${TARGET_NAME} VERSION 1.0.0)
...
set(CMAKE_CXX_COMPILER ${CPP_COMPILER})
set(CMAKE_C_COMPILER ${C_COMPILER})
...
target_compile_features(${TARGET_NAME} PUBLIC cxx_std_14)

```

I get, with gcc 5.5.0 (Ubuntu 16.04):

```auto
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?

Thanks

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [February 12, 2021, 5:07pm UTC](https://discourse.cmake.org/t/proper-way-to-set-compiler-and-language-standard-in-cmake/2756/2 "2021-02-12T17:07:03Z")

</div>

> [@adaldev](#):
>
> What is the proper way, in modern CMake, to choose the compiler (and to change it, on demand)?

Either using a [toolchain file](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html), using `cmake -DCMAKE_${LANG}_COMPILER=` on the _first_ configure, or `CC=… CXX=… cmake` on the _first_ configure.

> [@adaldev](#):
>
> Is it possible from a CMakeLists?

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

> [@adaldev](#):
>
> What is the proper way, in modern CMake, to set the language standard use?  
> Is it possible from a CMakeLists?

`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`).

---

<div class="post-metadata">

### Author: ![adaldev](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/9dc877/32.png) [@adaldev](https://discourse.cmake.org/u/adaldev)
#### Post date: [February 15, 2021, 6:11pm UTC](https://discourse.cmake.org/t/proper-way-to-set-compiler-and-language-standard-in-cmake/2756/3 "2021-02-15T18:11:53Z")

</div>

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.

Regards

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [February 15, 2021, 6:19pm UTC](https://discourse.cmake.org/t/proper-way-to-set-compiler-and-language-standard-in-cmake/2756/4 "2021-02-15T18:19:27Z")

</div>

> [@adaldev](#):
>
> the best way is so to delete the build tree before calling cmake again with a -DCMAKE\_CXX\_COMPILER=… for instance?

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

> [@adaldev](#):
>
> 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?)

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

```

> [@adaldev](#):
>
> I must support xenial versions as my users may not be able to upgrade their applications.

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

---

<div class="post-metadata">

### Author: ![adaldev](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/9dc877/32.png) [@adaldev](https://discourse.cmake.org/u/adaldev)
#### Post date: [February 19, 2021, 12:43pm UTC](https://discourse.cmake.org/t/proper-way-to-set-compiler-and-language-standard-in-cmake/2756/5 "2021-02-19T12:43:52Z")

</div>

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.

Regards

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [February 19, 2021, 1:46pm UTC](https://discourse.cmake.org/t/proper-way-to-set-compiler-and-language-standard-in-cmake/2756/6 "2021-02-19T13:46:41Z")

</div>

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?

---

<div class="post-metadata">

### Author: ![adaldev](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/9dc877/32.png) [@adaldev](https://discourse.cmake.org/u/adaldev)
#### Post date: [February 19, 2021, 6:06pm UTC](https://discourse.cmake.org/t/proper-way-to-set-compiler-and-language-standard-in-cmake/2756/7 "2021-02-19T18:06:06Z")

</div>

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

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [February 19, 2021, 6:58pm UTC](https://discourse.cmake.org/t/proper-way-to-set-compiler-and-language-standard-in-cmake/2756/8 "2021-02-19T18:58:14Z")

</div>

Hmm. That seems odd. Could you please file [an issue](https://gitlab.kitware.com/cmake/cmake/-/issues) with more details about your setup and a small example project?

---

<div class="post-metadata">

### Author: ![adaldev](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/9dc877/32.png) [@adaldev](https://discourse.cmake.org/u/adaldev)
#### Post date: [February 19, 2021, 7:54pm UTC](https://discourse.cmake.org/t/proper-way-to-set-compiler-and-language-standard-in-cmake/2756/9 "2021-02-19T19:54:20Z")

</div>

hum, embarrassing. I’ve just found the problem: it was a “chair-keyboard interface” issue 😉  
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.

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [February 19, 2021, 8:20pm UTC](https://discourse.cmake.org/t/proper-way-to-set-compiler-and-language-standard-in-cmake/2756/10 "2021-02-19T20:20:47Z")

</div>

Thanks for reporting back 🙂 .
