I've been searching around, and this issue seems to come up a lot in various forms. It was most often caused by a missing compiler, which would say C and CXX compilers are unknown
.
In my case however, that's not what's happening. I have C and C++ compilers on my machine, and e.g. through Visual Studio everything compiles fine. Through cmake
however, this happens:
> cmake .
Output:
-- Building for: Visual Studio 14 2015
-- The C compiler identification is MSVC 19.0.24215.1
-- The CXX compiler identification is MSVC 19.0.24215.1
CMake Error at CMakeLists.txt:12 (project):
No CMAKE_C_COMPILER could be found.
CMake Error at CMakeLists.txt:12 (project):
No CMAKE_CXX_COMPILER could be found.
-- Configuring incomplete, errors occurred!
I'm a bit confused. How can it find the compiler, but then forget about it? There are also no errors in the output log (or if there are, I don't recognize them).
These are the very last lines in CMakeOutput.log
:
Compilation of the CXX compiler identification source "CMakeCXXCompilerId.cpp" produced "CompilerIdCXX.exe"
Compilation of the CXX compiler identification source "CMakeCXXCompilerId.cpp" produced "CompilerIdCXX.vcxproj"
The CXX compiler identification is MSVC, found in "[...]/CMakeFiles/3.9.1/CompilerIdCXX/CompilerIdCXX.exe"
The source CMakeLists.txt
is part of an existing, working project, so I'm led to believe this is a local configuration issue.
Manually specifying these compilers as the following will make cmake discover them and generate the project (real paths are used here on purpose, as I suspect the paths themselves can be perhaps the cause of this error, note the foreign characters):
SET(CMAKE_C_COMPILER "D:/Programfájlok (x86)/Microsoft Visual Studio 14.0/VC/bin")
SET(CMAKE_CXX_COMPILER "D:/Programfájlok (x86)/Microsoft Visual Studio 14.0/VC/bin")
Note: these go at the top of the CmakeLists.txt
file.
The question still stands as in why can't cmake determine these paths automatically, when it can determine the correct generator.
According to the FAQ, it is not recommended to set compiler paths in CmakeLists.txt, so another approach can be the following:
cmake
-D CMAKE_C_COMPILER="path/to/compiler"
-D CMAKE_CXX_COMPILER="path/to/compiler"
..
There have been previous reports of CMake's Visual Studio generators breaking due to unicode paths (here, here), and while this issue seems to be long fixed (CMake commit), it could indicate that Unicode paths may be still causing trouble in some cases.
Based on your description, it doesn't sound like an installation issue - a fresh Visual Studio installation, that otherwise works properly. Since when specifying CMAKE_CXX_COMPILER
manually, the build is working, my best guess would be that there's may be something to do with CMake's compiler detection involving Unicode paths.
The above is just an educated guess. However, if it's your own project, and/or you have control on how CMake is invoked, specifying the compilers to CMake with -DCMAKE_C_COMPILER
and -DCMAKE_CXX_COMPILER
is perfectly fine.
How can it find the compiler, but then forget about it?
The macro in charge of determining the compiler version is called CMAKE_DETERMINE_COMPILER_ID
(in CMakeDetermineCompilerId.cmake). Going through the macro code, there are several defines that should be set during normal operation, namely CMAKE_CXX_COMPILER_ID
, CMAKE_CXX_COMPILER_VERSION
and CMAKE_CXX_COMPILER_ID_TOOL
. In your case, it seems that CMAKE_CXX_COMPILER_ID
and CMAKE_CXX_COMPILER_VERSION
are set, but for some reason CMAKE_CXX_COMPILER_ID_TOOL
isn't:
# Display the final identification result.
if(CMAKE_${lang}_COMPILER_ID)
if(CMAKE_${lang}_COMPILER_VERSION)
set(_version " ${CMAKE_${lang}_COMPILER_VERSION}")
else()
set(_version "")
endif()
message(STATUS "The ${lang} compiler identification is "
"${CMAKE_${lang}_COMPILER_ID}${_version}")
else()
message(STATUS "The ${lang} compiler identification is unknown")
endif()
# Check if compiler id detection gave us the compiler tool.
if(CMAKE_${lang}_COMPILER_ID_TOOL)
set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER_ID_TOOL}" PARENT_SCOPE)
elseif(NOT CMAKE_${lang}_COMPILER)
set(CMAKE_${lang}_COMPILER "CMAKE_${lang}_COMPILER-NOTFOUND" PARENT_SCOPE)
endif()
CMAKE_CXX_COMPILER_ID_TOOL
is set by the CMAKE_DETERMINE_COMPILER_ID_BUILD
macro, in that same file. There's quite some code involved in setting CMAKE_CXX_COMPILER_ID_TOOL
(running a process, capturing its output, regex matching, etc.), so it's theoretically possible that some of it (or even the invoked Visual Studio commands) doesn't behave well with Unicode paths.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With