2

I'd like to set the compiler version in CMake so I can switch between GCC and Clang just by commenting out a few lines.

Below is the top of my CMake script, with the two additional lines setting GCC as the compiler:

cmake_minimum_required(VERSION 3.4.1...3.17.2)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")

project(test_project C CXX)

set (CMAKE_C_COMPILER "/usr/bin/gcc")       # Adding these causes infinite loop
set (CMAKE_CXX_COMPILER "/usr/bin/g++")

message(STATUS "Compiler ID:   ${CMAKE_CXX_COMPILER_ID}")
message(STATUS "Compiler Vers: ${CMAKE_CXX_COMPILER_VERSION}")

However, when I add the above two lines and run cmake .. the script enters an infinite loop, outputting:

You have changed variables that require your cache to be deleted
Configure will be re-run and you may have to reset some variables
The following variables have changed:
CMAKE_C_COMPILER= /usr/bin/cc
CMAKE_CXX_COMPILER= /usr/bin/c++
CMAKE_CXX_COMPILER= /usr/bin/c++
CMAKE_C_COMPILER= /usr/bin/cc
CMAKE_CXX_COMPILER= /usr/bin/c++
CMAKE_C_COMPILER= /usr/bin/cc

I'd eventually like to have something like this:

cmake_minimum_required(VERSION 3.4.1...3.17.2)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")

project(test_project C CXX)

set (CMAKE_C_COMPILER "/usr/bin/gcc")
set (CMAKE_CXX_COMPILER "/usr/bin/g++")
#set (CMAKE_C_COMPILER "/usr/bin/clang")
#set (CMAKE_CXX_COMPILER "/usr/bin/clang++")

message(STATUS "Compiler ID:   ${CMAKE_CXX_COMPILER_ID}")
message(STATUS "Compiler Vers: ${CMAKE_CXX_COMPILER_VERSION}")

Anyone know what's wrong?

intrigued_66
  • 16,082
  • 51
  • 118
  • 189
  • 1
    See also that [my answer](https://stackoverflow.com/a/63944545/3440745) why setting a compiler **after** the `project()` call is simply wrong. – Tsyvarev Dec 16 '22 at 19:02

2 Answers2

3

It seems to be an ancient CMake bug, where the workaround proposed is just putting the variables before the project command:

cmake_minimum_required(VERSION 3.17.2)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")
set(CMAKE_C_COMPILER "/usr/bin/gcc")
set(CMAKE_CXX_COMPILER "/usr/bin/g++")

project(test_project C CXX)
...

EDIT:

As other mentioned, this is not actually a bug, but design decision: project command selects compiler based on the provided settings, and it never should be altered after the command comes into play.

The Dreams Wind
  • 8,416
  • 2
  • 19
  • 49
  • Do you know why my two bottom `message` lines are now outputting nothing? Is there any way I can output the compiler being used? – intrigued_66 Dec 16 '22 at 18:37
  • @intrigued_66 if you put the `message` commands before `project` as well, just move them back, *after* `project`. That's because `project` command selects the actual compiler used, and both variables (`CMAKE__COMPILER_VERSION` / `CMAKE__COMPILER_ID`) are only set *after* `project` command – The Dreams Wind Dec 17 '22 at 09:03
0

BTW, these variables are not for the set by the project. This is done intentionally so a user may choose the compiler he wants to build the project. The project maintainer should not decide for the user what compiler to use. Who told you that it must be only /usr/bin/*? What if GCC came from SCL (on RHEL/CentOS) where it gonna be installed to /opt/rh/devtoolset-N/... ... Please leave to users the freedom to choose what compiler to use!

These variables must be set via CLI, initial cache, toolchain file, presets, or environment variables.

zaufi
  • 6,811
  • 26
  • 34