2
votes

As part of our build process, we need to record the details of the machine and compiler. Since the compiler can be changed from the system default by setting CMAKE_CXX_COMPILER, I figure the safest way to detect the compiler is to ask cmake itself what it's using.

This is (the important part of) the toolchain file that we use for our project:

SET(CMAKE_CXX_FLAGS "-std=c++11")
SET(CMAKE_BUILD_TYPE Release)
SET(CMAKE_OSX_ARCHITECTURES "x86_64" )
SET(CMAKE_CXX_COMPILER /usr/bin/clang++)
SET(CMAKE_C_COMPILER /usr/bin/clang)

So now I've created a CMakeLists.txt file, separate from the one we use for our main project, that looks like this:

cmake_minimum_required(VERSION 2.8)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version
   OUTPUT_VARIABLE cxx_version)
FILE(WRITE "/tmp/compiler.txt" "Compiler: ${CMAKE_CXX_COMPILER} is ${cxx_version}")

When I run cmake on this CMakeLists.txt and pass it the toolchain file, I've got a reasonably secure method for determining which compiler is being used for the main project. That is to say, while it's possible that some sloppy developer might add a "-DCMAKE_CXX_COMPILER" to the command line for the main project (and then /tmp/compiler.txt would be wrong), it's more likely that developers would edit the toolchain file (and then /tmp/compiler.txt would contain the correct information).

The problem is, I would like to also check whether c++11 has been enabled, but in my CMakeLists.txt file, I can't check the settings of any of the CMAKE variables. If I do this:

MESSAGE(STATUS "CMAKE_OSX_ARCHITECTURES are ${CMAKE_OSX_ARCHITECTURES}")
MESSAGE(STATUS "CMAKE_BUILD_TYPE is ${CMAKE_BUILD_TYPE}")
MESSAGE(STATUS "CMAKE_CXX_FLAGS are ${CMAKE_CXX_FLAGS}")

The messages say that all these values are empty. If I add some of my own values to my toolchain file and print out their values in my CMakeLists.txt they are correct, so I know the toolchain file is being processed.

I've seen some hints that perhaps cmake is discarding the value of CMAKE_CXX_FLAGS because my CMakeLists.txt doesn't compile anything. Is this possible? Or does cmake just internalize the values of its variables in a way that my CMakeLists.txt can't see them?

1
Using "CACHE STRING" in my toolchain file solves this problem, though I'm not sure it's the right solution or not ... thoughts? - Betty Crokker

1 Answers

0
votes

You need to write this variable to cache, example:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" CACHE STRING "some info" FORCE)

Note that flags updating after project command:

message("release flags: ${CMAKE_CXX_FLAGS_RELEASE}")
cmake_minimum_required(VERSION 2.8.4)
project(foo CXX)
message("release flags: ${CMAKE_CXX_FLAGS_RELEASE}")

Output:

release flags:
-- The CXX compiler identification is GNU 4.8.2
-- Check for working CXX compiler: /usr/bin/c++.exe
-- Check for working CXX compiler: /usr/bin/c++.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
release flags: -O3 -DNDEBUG
-- Configuring done
-- Generating done
-- Build files have been written to: ...