168

My OS is centos which has a default gcc in path /usr/bin/gcc. But it is old, I need a new version of gcc. So I install a new version in a new path /usr/local/bin/gcc.

But when I run cmake, it still uses the old version gcc path(/usr/bin/gcc) . How can I specify the gcc to new path(/usr/local/bin/gcc).

I have tried to overwrite /usr/bin/gcc with /usr/local/bin/gcc, but it not work.

mustafagonul
  • 1,139
  • 1
  • 15
  • 32
tidy
  • 4,747
  • 9
  • 49
  • 89
  • 3
    I think it's a good practice to install alternate gcc version into `/opt` rather than `/usr/local`. Preferably `/opt/gcc-x.y.z`. This way, if you need an even newer version, you won't have any trouble uninstalling the previous one. – user666412 May 25 '18 at 15:24

7 Answers7

293

Do not overwrite CMAKE_C_COMPILER, but export CC (and CXX) before calling cmake:

export CC=/usr/local/bin/gcc
export CXX=/usr/local/bin/g++
cmake /path/to/your/project
make

The export only needs to be done once, the first time you configure the project, then those values will be read from the CMake cache.


UPDATE: longer explanation on why not overriding CMAKE_C(XX)_COMPILER after Jake's comment

I recommend against overriding the CMAKE_C(XX)_COMPILER value for two main reasons: because it won't play well with CMake's cache and because it breaks compiler checks and tooling detection.

When using the set command, you have three options:

  • without cache, to create a normal variable
  • with cache, to create a cached variable
  • force cache, to always force the cache value when configuring

Let's see what happens for the three possible calls to set:

Without cache

set(CMAKE_C_COMPILER /usr/bin/clang)
set(CMAKE_CXX_COMPILER /usr/bin/clang++)

When doing this, you create a "normal" variable CMAKE_C(XX)_COMPILER that hides the cache variable of the same name. That means your compiler is now hard-coded in your build script and you cannot give it a custom value. This will be a problem if you have multiple build environments with different compilers. You could just update your script each time you want to use a different compiler, but that removes the value of using CMake in the first place.

Ok, then, let's update the cache...

With cache

set(CMAKE_C_COMPILER /usr/bin/clang CACHE PATH "")
set(CMAKE_CXX_COMPILER /usr/bin/clang++ CACHE PATH "")

This version will just "not work". The CMAKE_C(XX)_COMPILER variable is already in the cache, so it won't get updated unless you force it.

Ah... let's use the force, then...

Force cache

set(CMAKE_C_COMPILER /usr/bin/clang CACHE PATH "" FORCE)
set(CMAKE_CXX_COMPILER /usr/bin/clang++ CACHE PATH "" FORCE)

This is almost the same as the "normal" variable version, the only difference is your value will be set in the cache, so users can see it. But any change will be overwritten by the set command.

Breaking compiler checks and tooling

Early in the configuration process, CMake performs checks on the compiler: Does it work? Is it able to produce executables? etc. It also uses the compiler to detect related tools, like ar and ranlib. When you override the compiler value in a script, it's "too late", all checks and detections are already done.

For instance, on my machine with gcc as default compiler, when using the set command to /usr/bin/clang, ar is set to /usr/bin/gcc-ar-7. When using an export before running CMake it is set to /usr/lib/llvm-3.8/bin/llvm-ar.

Seonghyeon Cho
  • 171
  • 1
  • 3
  • 11
Guillaume
  • 10,463
  • 1
  • 33
  • 47
  • Equivalent for the lazy, if the proper compilers are set in your $PATH: > export CC=`which gcc` > export CXX=`which g++` – gerardw Mar 17 '14 at 15:13
  • 15
    Equivalent for the lazy, if the proper compilers are set in your $PATH: `export CC=\`which gcc\` export CXX=\`which g++\` ` – gerardw Mar 17 '14 at 15:19
  • If CC/CXX differ from path, I get `Incorrect 'gcc' version 'compiler.version=5.3' is not the one detected by CMake: 'GNU=4.8' ` – Lilith River Feb 25 '16 at 18:02
  • 1
    How do I do this if I'm on Windows? – mr5 Nov 02 '16 at 02:31
  • @mr5 Not tested, but supposed you should be able to do `set CC=...` in a Command Prompt. – Yongwei Wu Dec 29 '16 at 05:27
  • Why do you recommend against using CMAKE_C_COMPILER and CMAKE_CXX_COMPILER? – Jake Aug 23 '17 at 04:59
  • @Jake it would have been a bit too long to answer in a comment, so I updated my answer :) – Guillaume Sep 18 '17 at 06:26
  • 7
    Actually, setting `CMAKE_C_COMPILER` works well provided you do it using the command line: `$ cmake -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ /path/to/source`. – Erwan Legrand Oct 13 '17 at 12:54
  • 1
    This solution doesn’t always work. You need to clear the CMake cache for it to re-read the `CC` and `CXX` environment variables. It also assumes Bash or similar shell. This is an up-to-date answer without these limitations: https://stackoverflow.com/a/50494125/7328782 – Cris Luengo Jun 12 '18 at 02:59
  • An even lazier solution if you want something correctly named that appears first in your path `export CC=gcc-11` or just `export CC=clang` works.@gerardw – Spyros Mourelatos Jun 14 '21 at 10:23
45

This question is quite old but still turns up on Google Search. The accepted question wasn't working for me anymore and seems to be aged. The latest information about cmake is written in the cmake FAQ.

There are various ways to change the path of your compiler. One way would be

Set the appropriate CMAKE_FOO_COMPILER variable(s) to a valid compiler name or full path on the command-line using cmake -D. For example:

cmake -G "Your Generator" -D CMAKE_C_COMPILER=gcc-4.2 -D CMAKE_CXX_COMPILER=g++-4.2 path/to/your/source

instead of gcc-4.2 you can write the path/to/your/compiler like this

 cmake -D CMAKE_C_COMPILER=/path/to/gcc/bin/gcc -D CMAKE_CXX_COMPILER=/path/to/gcc/bin/g++ .
lambda
  • 3,295
  • 1
  • 26
  • 32
  • 2
    I was doing so while building an old project on an old compiler (GCC 5.3) while a newer compiler (GCC 7.3) was sourced in the environment. It built fine and worked on my machine, but once I moved the executable to a different machine I realized the program is linked to libstdc++.so from the sourced 7.3 instead of the requested 5.3... – Adam Badura Sep 02 '19 at 07:39
  • 1
    This works for me while the accepted one did not. – floodking Aug 25 '21 at 00:23
8

Set CMAKE_C_COMPILER to your new path.

See here: http://www.cmake.org/Wiki/CMake_Useful_Variables

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
5

Change CMAKE_<LANG>_COMPILER path without triggering a reconfigure

I wanted to compile with an alternate compiler, but also pass -D options on the command-line which would get wiped out by setting a different compiler. This happens because it triggers a re-configure. The trick is to disable the compiler detection with NONE, set the paths with FORCE, then enable_language.

project( sample_project NONE )

set( COMPILER_BIN /opt/compiler/bin )
set( CMAKE_C_COMPILER ${COMPILER_BIN}/clang CACHE PATH "clang" FORCE )
set( CMAKE_CXX_COMPILER ${COMPILER_BIN}/clang++ CACHE PATH "clang++" FORCE )

enable_language( C CXX )

Use a Toolchain file

The more sensible choice is to create a toolchain file.

set( CMAKE_SYSTEM_NAME Darwin )

set( COMPILER_BIN /opt/compiler/bin )
set( CMAKE_C_COMPILER ${COMPILER_BIN}/clang CACHE PATH "clang" )
set( CMAKE_CXX_COMPILER ${COMPILER_BIN}/clang++ CACHE PATH "clang++" )

Then you invoke Cmake with an additional flag

cmake -D CMAKE_TOOLCHAIN_FILE=/path/to/toolchain_file.cmake ...
Cameron Lowell Palmer
  • 21,528
  • 7
  • 125
  • 126
4

Export should be specific about which version of GCC/G++ to use, because if user had multiple compiler version, it would not compile successfully.

 export CC=path_of_gcc/gcc-version
 export CXX=path_of_g++/g++-version
 cmake  path_of_project_contain_CMakeList.txt
 make 

In case project use C++11 this can be handled by using -std=C++-11 flag in CMakeList.txt

thoni56
  • 3,145
  • 3
  • 31
  • 49
R.Chatsiri
  • 107
  • 2
  • 11
3

An alternative solution is to configure your project through cmake-gui, starting from a clean build directory. Among the options you have available at the beginning, there's the possibility to choose the exact path to the compilers

Antonio
  • 19,451
  • 13
  • 99
  • 197
2

This not only works with cmake, but also with ./configure and make:

./configure CC=/usr/local/bin/gcc CXX=/usr/local/bin/g++

Which is resulting in:

checking for gcc... /usr/local/bin/gcc
checking whether the C compiler works... yes
Martin Zeitler
  • 1
  • 19
  • 155
  • 216