CMake -DCMAKE_CXX_COMPILER works but SET(CMAKE_CXX_COMPILER ...) is ignored?

Publish date: 2024-05-06

Been messing around trying to set the CPP compiler to g++ using the following line in my toolchain file.

# specify the cross compiler SET(CMAKE_CXX_COMPILER:FILEPATH /opt/qnx641/host/linux/x86/usr/bin/arm-unknown-nto-qnx6.4.0-g++) 

This didn't appear to be used, so I tried something right out just to be sue

SET(CMAKE_C_COMPILER:FILEPATH /junk/gcc) 

Okay, overkill, but this way I'm definitely sure CMake isn't doing any funny inferences from the path and command structure I was passing in.

I'd gone down this route by looking at the CMake Cross Compiling page where it talks about toolchain files.

So read around a bit and decided to do it from the command line as this QA thread showed that the command line -D would override cached vars.

This worked!

So my question is, does anyone know why when I do not use the -D command line option how CMake finds my cross-compiler path and exename but ignores the SET(CMAKE_CXX_COMPILER... line in my toolchain.

I have, before each build deleted the build directory and the CMakeCache.txt file.

For completeness the command line I'm using is

rm CMakeCache.txt; rm -fr build; cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=./build -DMAKE_TOOLCHAIN_FILE=/path/to/toolchain-file.cmake -C CMakeCrossCompile-TryRunResult-qnx-armle.cmake . 

The file CMakeCrossCompile-TryRunResult-qnx-armle.cmake does not contain CMAKE_CXX_COMPILER.

Any clue to what's giong on much appreciated!

I also used the -LA command line option to see the cached variables being used and its definitely not getting the right value from the SET command when the command linne -D... is not present...

EDIT: I found the following CMake Support Request that recommends using environment variables, found via this SO thread.

It seems that using the variables in the ToolChain file might be too late in the process? Strange, because it shows this method in the guide linked to above. Can any confirm/deny this? Thanks.

3 Answers

You just need to set it to the CACHE. For instance:

set(CMAKE_C_COMPILER gcc CACHE STRING "C compiler" FORCE) set(CMAKE_CXX_COMPILER g++ CACHE STRING "C++ compiler" FORCE) 
1

The SO answer you linked to has a link to the CMake FAQ. It says:

How do I use a different compiler?

...

Method 3 (avoid): use set()

Set the appropriate CMAKE_FOO_COMPILER variable(s) to a valid compiler name or full path in a list file using set(). This must be done before any language is set (ie before any project() or enable_language() command).

For example:

set(CMAKE_C_COMPILER "gcc-4.2")
set(CMAKE_CXX_COMPILER "/usr/bin/g++-4.2")

project("YourProjectName")

2

Thank you to everyone who answered. Neither of the two answers actually covered the real cause but were both very good attempts and very relevant so thank you for sparing your time to help me out... much appreciated.

The Problem & Solution

The problem I was having eventually boiled down to doing in-source builds... I have now learnt the beauty and importance of doing out-of-source builds! It was indeed a caching issue. I thought I was deleting everything necessary, but what I found in the in-source-build was that the toolchain file was not being accessed... due to caching.

Therefore the answer is USE OUT-OF-SOURCE-BUILDS. Then you can just kill the binary dir to emulate a cmake clean-like command. Then you can guarantee everything starts from scratch and nothing is cached... yay!

Some things I found useful along the way

View Cached Variables

Use the cmake options -LA. This will list cache variables from the CMake cache that are not marked internal.

Use -N to only load the cache and not run the scripts

CMake equivalent to #error

It was figuring out that the toolchain file was not being re-read that hit the nail on the head for me. To figure this one out I added the following line in the toolchain file...

MESSAGE(FATAL_ERROR "I am included") 

And guess what? no error occurred. however, once I'd cleaned all the necessary guff to get a clean cmake going the error was triggered.

Platform CMake Configuration... Included Automatically

This one foxed me for a time....

From http://www.cmake.org/Wiki/CMake_Cross_Compiling:

Once the system and the compiler are determined by CMake, it loads the corresponding files in the following order: Platform/${CMAKE_SYSTEM_NAME}.cmake (mandatory)

I had seen this originally but had searched for <CMakeList.txt directory>/Platform. I should have searched <CMakeList.txt directory>/Modfules/Platform (as well?)

In my toolchain file I have the following line...

SET(CMAKE_SYSTEM_NAME QNX) 

Therefore, CMake was searching for Platform/QNX.cmake as the Cross-Compiling guide said it would. The thing I didn't realise was this meant Modules/Platform/QNX.cmake.

The most interesting line here, which I thought was giving me a problem, but in the end wasnt (I still find the auto-inclusion of this file and interesting point to note for where some options are coming from etc...)

# force the language to be c++ since qnx only has gcc and not g++ and c++? set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> -x c++ <DEFINES> <FLAGS> -o <OBJECT> -c <SOURCE>") 

Hope someone finds this useful :)

ncG1vNJzZmirpJawrLvVnqmfpJ%2Bse6S7zGiorp2jqbawutJoaWxvZmd%2FcoGOnKSao5VisaS5wKScZpuorXqku8ypoKWdomLEsL7KrGSbraRiwKbAwqaYpJ1dmMW5ecKopKmhnJq%2FbrXSZqCgpp%2BnsqU%3D