This question already has an answer here:
-
How to debug CMakeLists.txt files?
3 answers
Is there a way to examine what cmake
is doing in a failing run? For example, I have a program depending on libbacktrace, which I can link to by gcc foo.c -lbacktrace
. But when I write a CMakeLists.txt
like
cmake_minimum_required(VERSION 2.8)
find_library (BACKTRACE_LIBRARY backtrace)
message (BACKTRACE_LIBRARY=${BACKTRACE_LIBRARY})
and type cmake <path>
, it prints out BACKTRACE_LIBRARY=BACKTRACE_LIBRARY-NOTFOUND
.
How do I go about figuring out where the problem is? What commands is cmake
executing before giving up on finding libbacktrace? Is it executing anything at all? In autoconf, the commands are all recorded in config.log
, but CMakeOutput.log
in this case is blank. Likewise, cmake --trace
only echoes the contents of CMakeLists.txt
after a bunch of system cmake files, which is useless in this case.
Please note that I'm not looking for a way to make this particular invocation of find_library
work - that's just an example. My question is: I have a CMakeLists.txt that isn't working as expected; what tools exist to help me figure out where and why it's failing?
There is no CMake debugger or similar¹. What you can do is:
Read the output of CMake, sometimes it already gives hints like "missing INCLUDE_MYLIB_DIR"). Delete you CMakeCache.txt and/or remove the build directory, to be sure you don't miss output because the result was cached. Repeat and check whether caching had an influence. You get more warnings (those meant for the author/developer of the CMake script, not for the user) with -Wdev
. More helpful options are --warn-uninitialized
, --warn-unused-vars
and --check-system-vars
, see the documentation for more details.
Check the generated files like the CMakeCache.txt
and additional files you generate like a config.h
or input files for Doxygen. Variables with values you expect different, are indicators for further research.
Have a look into CMakeError.log and CMakeOuput.log in the CMakeFiles sub-directory. Unfortunately, many test do not write into these files, but some do. For example C compiler runs put the compiler output there, which helps to find the problem with unintended flags or wrong (cross-)compilers.
Debug with printf. This means when you roughly know where you problem is located, output intermediate variables with message
. That is helpful, when you don't know how a branch or a sub-expression (a part of a expression with AND or OR) is evaluated. Further you can put messages like "in branch where mylib version is > 3.2" inside to follow the workflow.
Reduce complexity. Throw everything out you don't know, until your problem vanishes. Add the stuff again until the problem reappears. Sometimes it is easier to start a new module to reproduce the problem with a minimal example. Surprisingly, this often helps to pinpoint the problem.
Debug with --debug-output
(for debug output) --trace
(complete trace) and --trace-expand
(trace and expanded variables). For these it is extremely helpful to make progress with point 5., because otherwise the output will flood you.
¹Well, there are the steveire's CMake Daemon Tools. I haven't used them myself, but they claim to offer possibilities for introspection that seem to be pretty close to a debugger.
Edit: They are now called CMake-server and are going to be part of CMake 3.7. You can expect that many tools and IDEs will pick this up and improve the way we develop CMake.
Beside the mentioned flag --trace
(and it's variable-expanding sibling --trace-expand
) there is --debug-output
.
From the docs:
--debug-output
Put cmake in a debug mode.
Print extra information during the cmake run like stack traces with message(send_error ) calls.
This might give you the desired info. Maybe in combination with --trace
.