82

I can't find any info on it, but only the other way around (e.g., how to set CMake to use clang).

I've installed gcc-4.8 using brew, setup all dependencies, headers, etc, and now CMake refuses to use gcc.

I've set my bash profile with both aliases and actual entries:

export CC=/usr/bin/gcc
export CXX=/usr/bin/g++
alias gcc='gcc-4.8'
alias cc='gcc-4.8'
alias g++='g++-4.8'
alias c++='c++-4.8'

Yet CMake stubbornly refuses to use gcc and instead reverts back to clang:

air:build alex$ cmake -DCMAKE_BUILD_TYPE=DEBUG ..
-- The C compiler identification is Clang 5.1.0
-- The CXX compiler identification is Clang 5.1.0
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
Lindydancer
  • 25,428
  • 4
  • 49
  • 68
Ælex
  • 14,432
  • 20
  • 88
  • 129
  • The only way I've ever found to do this was to change the symbolic links in `/usr/bin`, which is tedious - there has to be a better way. – Paul R Jun 24 '14 at 07:14

5 Answers5

121

CMake doesn't (always) listen to CC and CXX. Instead use CMAKE_C_COMPILER and CMAKE_CXX_COMPILER:

cmake -DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_CXX_COMPILER=/usr/bin/g++ ...

See also the documentation.

Alternatively, you can provide a toolchain file, but that might be overkill in this case.

rubenvb
  • 74,642
  • 33
  • 187
  • 332
  • thanks that works, but surely there must be a way to set the gcc and g++ within my CMakeLists.txt, no? – Ælex Jun 24 '14 at 07:30
  • 6
    @Alex: Why would you do that? `CMakelists.txt` is meant to be platform/toolchain agnostic as much as possible. Don't force anything on anyone. Also, see [this CMake Wiki entry](http://www.cmake.org/Wiki/CMake_FAQ#How_do_I_use_a_different_compiler.3F). Using the `-D` syntax is the `Correct™` way. – rubenvb Jun 24 '14 at 07:40
  • If you really want to, you can detect system type and then set the compiler to use in your CMakeLists.txt. But as rubenvb writes, one should keep the config clear of system dependent configuration. – wojciii Jun 24 '14 at 10:09
  • @rubenvb Live example: project compiles fine on my macbook with clang, but doesn't with gcc on linux machine, and I want to force Cmake to use gcc on mine to see if I get the same problem. – Pietro Saccardi Nov 30 '14 at 20:14
  • 3
    @Pietro that's exactly why you wouldn't hardcode the toolchain in your CMakelists.txt, but instead, when you're doing your test build with GCC on your macbook, use the above command (or some variation with the correct paths of course...). – rubenvb Dec 01 '14 at 08:05
  • 21
    This answer is incorrect. CMake does honor the CC and CXX environment variables. The only caveat is that you must set them before running CMake, not before running make inside the generated build directory. Also, CMake caches the values of these variables, so once the build directory is created, you may need to remove the directory and re-generate it if you change compilers. – cmccabe Apr 14 '15 at 22:38
  • @cmccabe does it respect `CC`/`CXX` for every generator, or only Makefiles? – rubenvb Apr 15 '15 at 11:18
  • 2
    As for now (3 years later) CMake honors `CC` and `CXX` on Linux, but not on MacOS. Again hitting the problem... – Eric Platon Nov 16 '18 at 03:52
  • 2
    @Eric the `CC`/`CXX` is only used in case of the `Makefile` (all variants) and `Ninja` generators. – rubenvb Jan 21 '20 at 13:39
  • there could be some minor issues related to this solution when using the compiler identification string: if there is any specific to `GCC`, `cmake` won't understand that is running on `GCC` but still consider to use `AppleClang` explicitly if the CMakefiles.txt is using a `CMAKE_CXX_COMPILER_ID` to do some specific compiler specific statement based on `GNU` – Raffaello May 09 '20 at 15:15
  • Had to change the gcc/g++ paths to `/usr/bin/gcc-12`, `/usr/bin/g++-12` after I installed via brew: `$ brew install gcc@12`. – Dentrax Jun 22 '22 at 06:49
18

Current versions of CMake do not respect the CC and CXX environment variables like one would expect. Specifically if they are absolute paths to the compiler binaries they seem to be ignored. On my system with a freshly compiled cmake 3.7.1 I have to do cmake -H. -Bbuild -DCMAKE_C_COMPILER=$CC -DCMAKE_CXX_COMPILER=$CXX.

As others have stated it is not a great idea to force a compiler choice within your CMakeLists.txt, however if this is required for your use case here's how you do it:

cmake_minimum_required(VERSION 3.5) # Or whatever version you use

# THIS HAS TO COME BEFORE THE PROJECT LINE
set(CMAKE_C_COMPILER "gcc")
set(CMAKE_CXX_COMPILER "g++")
# THIS HAS TO COME BEFORE THE PROJECT LINE

project(my_project VERSION 0.0.0 LANGUAGES C CXX)

In this case cmake will fail if the indicated compiler is not found. Note that you must set these variables before the project line as this command is what finds and configures the compilers.

11

I guess the case in OP was run on a macOS, and the real problem is /usr/bin/gcc and /usr/bin/g++ by default are clang and clang++.

% ls -al /usr/bin/clang
-rwxr-xr-x  1 root  wheel  167088  8 Dec 07:39 /usr/bin/clang
% ls -al /usr/bin/gcc
-rwxr-xr-x  1 root  wheel  167088  8 Dec 07:39 /usr/bin/gcc
% /usr/bin/gcc --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 13.0.0 (clang-1300.0.29.30)
Target: x86_64-apple-darwin21.2.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

One way avoid that is to install gcc/g++ and then use the versioned binary names.

% which gcc-11 g++-11
/usr/local/bin/gcc-11
/usr/local/bin/g++-11
% gcc-11 --version
gcc-11 (Homebrew GCC 11.2.0_3) 11.2.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

So, instead of

cmake .. -DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_CXX_COMPILER=/usr/bin/g++

one would use

cmake .. -DCMAKE_C_COMPILER=/usr/local/bin/gcc-11 -DCMAKE_CXX_COMPILER=/usr/local/bin/g++-11
Hahnemann
  • 4,378
  • 6
  • 40
  • 64
Song Wang
  • 290
  • 2
  • 9
  • In my case (MacOS Monterey) the CC and CXX are empty, I added aliases to the correct gcc (instead of default gcc clang set up by XCode), and STILL cmake is ignoring all of this for an absolute path to XCode tools. Like you said you have to specify the compiler to CMake, but this is not related to the OS or system because Cmake is ignoring ALL of it anyway. – ymoreau May 19 '22 at 14:18
1

Just to add that, there is also a CMake variable CMAKE_Fortran_COMPILER to pick up GNU FORTRAN rather than clang FORTRAN. But it seems to be missing in the documentation

cmake -DCMAKE_Fortran_COMPILER=/usr/.../bin/gfortran-6.x.0
Gass
  • 7,536
  • 3
  • 37
  • 41
1

it should be enough to use CC and CXX environment variables, but in macOS are not "working as expected".

but it works in this way instead eg:

CXX="gcc-8" CC="gcc-8" cmake ..
Raffaello
  • 1,641
  • 15
  • 29