3

I am working on a template CMake file to use for future projects. I for my part am a huge fan of clang, but I don't want to force everyone using my projects to use clang too. The best case would be for it to simply work whatever compiler is present if clang isn't.
I found the following line, but in my test id didn't seem to do anything.

set(CMAKE_C_COMPILER_NAMES clang gcc icc cc)
set(CMAKE_CXX_COMPILER_NAMES clang++ g++ icpc c++ cxx)

What would be the best way to prioritize in the following order:

  1. clang
  2. gcc
  3. whatever is installed
Adam
  • 2,820
  • 1
  • 13
  • 33
  • 1
    CMake generally *does* work for whatever compiler is present, so if you want to choose Clang, you should set Clang as the compiler in the `cmake -D` command line options, as suggested [here](https://stackoverflow.com/a/45934279/3987854). I wouldn't impose the compiler preferences on the others in your project, just let CMake pick the best compiler for their environment. I'm not sure where you saw these variables like `CMAKE_CXX_COMPILER_NAMES`, but they are not special CMake variables, like `CMAKE_CXX_COMPILER` is. – Kevin Jun 18 '20 at 13:07
  • This question has merit. For example, I am presently building code that builds with both gcc and clang, but has extensive suppor for clang attributes to for exampel check thread locks. Most people just cmake && make so it would be really good if the code picked clang before gcc. – fuzzyTew May 25 '21 at 13:58

2 Answers2

2

You should let CMake use the compiler that the user has configured it to use, or what they've configured to be the default, or what their system uses by default. Adding compiler selection code into CMakeLists.txt is counter-productive.

If you know that the program won't work with particular compiler, you could check that and show a warning message.

As the user, you can specify The CC and CXX environment variables to choose the compiler, or CMAKE_<LANG>_COMPILER variable which overrides the former.

usr1234567
  • 21,601
  • 16
  • 108
  • 128
eerorika
  • 232,697
  • 12
  • 197
  • 326
  • 1
    I can't really configure clang as my default, because the defaults are configured to please my boss. for my own projects, I want to overwrite the defaults, but in a way that does not interfere with other people.at least until I built some tooling for that – Stefan Schmelz Jun 19 '20 at 14:44
0

I found I had to set the variables before the initial project() line:

cmake_minimum_required(VERSION 3.12)

set(CMAKE_C_COMPILER_NAMES clang gcc icc cc)
set(CMAKE_CXX_COMPILER_NAMES clang++ g++ icpc c++ cxx)

project(foo C CXX)

If you visit the source code for the file that does this, you can see that it loads system-specific configuration files to set these variables. You might be able to make your solution more compatible by including those and reusing their results:

cmake_minimum_required(VERSION 3.12)

include(Platform/${CMAKE_SYSTEM_NAME}-Determine-C OPTIONAL)
include(Platform/${CMAKE_SYSTEM_NAME}-C OPTIONAL)
set(CMAKE_C_COMPILER_NAMES clang gcc icc cc ${CMAKE_C_COMPILER_NAMES})

include(Platform/${CMAKE_SYSTEM_NAME}-Determine-CXX OPTIONAL)
include(Platform/${CMAKE_SYSTEM_NAME}-CXX OPTIONAL)
set(CMAKE_CXX_COMPILER_NAMES clang++ g++ icpc c++ cxx ${CMAKE_CXX_COMPILER_NAMES})

project(foo C CXX)

But further review of CMake's internals and ideally communication with the cmake developers around the issue is advised here, because future implementation changes in cmake could alter the functionality. If you open an issue with them around the use-case, they may express the best available solution. They will then have that solution in mind for further code improvements, giving it better compatibility.

fuzzyTew
  • 3,511
  • 29
  • 24