Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting CMake CHECK_CXX_COMPILER_FLAG to work

Tags:

cmake

Note: This is my first time using CMake. I don't know much about it, so I'm just posting a bunch of information to see if anyone can see my problem.

I would like the ability to automatically determine which c++11 flag is appropriate, given my compiler. There are many examples of this line. Here is my CMakeLists.txt following such an example:

cmake_minimum_required (VERSION 2.8)

#Add the c++11 flag, whatever it is
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG(-std=c++11 COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG(-std=c++0x COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
  message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()

project(AnalyzeGames)
set(AnalyzeGames_SRCS AnalyzeGames.cpp)
add_executable(AnalyzeGames ${AnalyzeGames_SRCS})

Here is my cmake output when trying to use this file: http://pastebin.com/3AUwqffD

Here is CMakeError.log: http://pastebin.com/EbNKvGt8

Here is CMakeOutput.log: http://pastebin.com/kVJ0enJC

echo $CC: /usr/bin/gcc

echo $CXX: /usr/bin/g++

I can compile a simple test executable with g++ using either flag manually.

cmake --version: cmake version 2.8.12.2

For some reason CMake is not recognizing that my compiler does support both of those flags.

like image 754
selecsosi Avatar asked Aug 22 '14 16:08

selecsosi


People also ask

How do I force CMake to use a specific compiler?

If you want, e.g., to use clang instead of defaulted gcc , then either: Pass -DCMAKE_C_COMPILER=<compiler> to cmake when configure the project. That way CMake will use this compiler instead of default one and on the project() call it will adjust all flags for the specified compiler.

Does CMake need compiler?

At a minimum, using CMake requires a C compiler, that compiler's native build tools, and a CMake executable. CMake was written in C++, requires only a C++ compiler to build, and precompiled binaries are available for most systems.

What is Cmake_cxx_compiler_id?

CMAKE_CXX_COMPILER_ID : The unique compiler identification string. CMAKE_COMPILER_IS_GNUCXX : True if the C++ compiler is part of GCC. CMAKE_CXX_COMPILER_VERSION : A string of the C++ compiler version. CMAKE_CXX_COMPILER : Path to the selected C++ compiler. CMAKE_C_COMPILER : Path to the selected C compiler.


2 Answers

The cmake output tells you that it does not recognize the '.cxx' extension because it doesn't know that your project is a C++ project. To fix this, you should enable C++ in the project command. Try to change the following line:

project(AnalyzeGames)

to:

project(AnalyzeGames CXX)

and then move it to the 2nd line of the CMakeLists.txt, right under cmake_minimum_required. The configuration should work as expected after this.

like image 174
atsui Avatar answered Sep 23 '22 06:09

atsui


TLDR

Compiler checks are only performed in the variable passed is not previously defined, which includes in the cache from previous failed attempts. Use unset(my_var CACHE) to force checking to always occur, or just be aware of this behaviour and clear the cache manually when needed.

Detail

I too had this problem (with cmake 2.8.12.2) and I had to turn on trace output, and step through the code to get a similar toy build to work I had make sure the variables I used (COMPILER_SUPPORTS_CXX11_*) in these calls:

CHECK_CXX_COMPILER_FLAG(-std=c++11 COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG(-std=c++0x COMPILER_SUPPORTS_CXX0X) 

Were set such that they named themselves:

set(COMPILER_SUPPORTS_CXX11 "COMPILER_SUPPORTS_CXX11")

The other posters solution didn't work for me, it mainly just seemed to limit the detecting of compilers to just CXX and ignored the C compiler.

The issue appears to be with this line of code in the cmake module:

if("${VAR}" MATCHES "^${VAR}$")

Which in the trace output is:

/usr/share/cmake/Modules/CheckCXXSourceCompiles.cmake(30):  if(COMPILER_SUPPORTS_CXX0X MATCHES ^COMPILER_SUPPORTS_CXX0X$ )

It looks as if the expression on the left of the MATCHES is replaced with the variables value, but the expression on the right is assumed to be plain text.

If the MATCH fails then the main part of the macro is skipped and according the to the log the check fails.

Looking at later versions of this macro online it looks as if this line has changed to only perform the compile check if the variable is undefined.

It as at this point that I realise that this is the intent / hack of the original code; if the X is undefined then "X" MATCHES "^X$" will be true, but then the compile check can be performed, fail for some other reason and then never be performed again.

So the solution is either force unset of variable in cache before calling the macro using:

 unset(COMPILER_SUPPORTS_CXX0X CACHE)

Or clear the cache manually and be prepared for this behaviour.

like image 41
Voltaire Avatar answered Sep 26 '22 06:09

Voltaire