Search code examples
c++makefilecmakeninja

CMake generated Ninja project fails at compiling with GCC


I have a cross platform CMake project that works perfectly with make/gcc on Linux and with MSVC on Windows. I wanted to give ninja a try and compare it with make. This is how I am creating the ninja project:

cmake -GNinja ../Source/

and then I run

ninja

but it fails with this error

/usr/bin/c++ -DmyPreprocessors ... -ImyIncludes ... -g3 -o0 -m32 -MMD -MT CMakeFiles/myProj.dir/myCode.cpp.o -MF CMakeFiles/myProj.dir/myCode.cpp.o.d -o CMakeFiles/myProj.dir/myCode.cpp.o -c /path/to/myCode.cpp 

cc1plus: fatal error: CMakeFiles/myProj.dir/myCode.cpp.d: No such file or directory

and when I check CMakeFiles/myProj.dir/ there is no myCode.cpp.d file.

But when I change the compiler to clang everything magically works! Ninja starts compiling and then successfully links.

When I run ninja in verbose mode I get the exact same command except the compiler is clang (/usr/bin/c++ => /usr/bin/clang++-3.9).

what is going on here?

EDIT:

Here is a sample CMakeLists.txt file that I used to reproduce the same error:

cmake_minimum_required(VERSION 3.5)
project(randomProj)

set(SOURCE_FILES myFile.cpp)

include_directories(Generic)

set(EXECUTABLE "TEST")

add_executable(${EXECUTABLE} ${SOURCE_FILES})
set(LIBRARY_SEARCH_PATH ${CMAKE_SOURCE_DIR}/path/to/my/libs)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w -g3 -o0")
target_link_libraries(${EXECUTABLE}  ${LIBRARIES})

and my myFile.cpp is this:

int main(){}

I did not specify anything explicitly for gcc. For clang however I just export the CC and CXX flags:

export CC=clang-3.9
export CXX=clang++-3.9

and then I call cmake.


Solution

  • Turning my comment into an answer: The -o flag is for stating the compiler output file, which is also done by the CMake generator itself, while the -O flag selects the optimization level. While it seems to be ignored by the make files produced by the make generator, this wrong flag seems to cause the ninja generator to produce wrong compiler commands.

    Anyway removing the -o0 flag or turning it into -O0 solves the problem in your short example and makes the ninja version to compile also.