28

When cmake encounters an error, sometimes it does not stop instantly but continues to process all CMake files. It is only at the end of the treatment that we learn that there is an error, so we have to go back up the whole log to see where it is located.

Is there any option, variable or means to stop CMake just after the first error?

Clarification: I'm not trying to stop the compilation of source code but the CMake generation (e.g. on Linux the generation of the Makefiles).

Here is an example (this is not my real project, this is specifically designed to generate errors). My file CMakeLists.txt:

cmake_minimum_required(VERSION 3.6)
project(test)
set_property(TARGET foo PROPERTY PROP1 TRUE)
set_property(TARGET bar PROPERTY PROP2 TRUE)

And when i run cmake . I get the output :

CMake Error at CMakeLists.txt:3 (set_property):
  set_property could not find TARGET foo.  Perhaps it has not yet been
  created.

CMake Error at CMakeLists.txt:4 (set_property): set_property could not find TARGET bar. Perhaps it has not yet been created.

-- Configuring incomplete, errors occurred!

What I would like to know is if cmake has the possibility to stop just after the first reported error.

louisiuol
  • 381

4 Answers4

0

You could try using a tool like awk or sed to parse the CMake output and extract the first error message. Here is an example of how you could use both:

$ cmake . 2>&1 | awk '/^CMake Error/ { print; exit }' // or
$ cmake . 2>&1 | sed -n '/^CMake Error/{p;q;}'

This will print the first error message that CMake outputs and then exit. You could then use this output to help identify the source of the error.

mhadidg
  • 1,091
0

You could use less or ccmake to page through the output, starting at the top. The controls are part of less, and it does not fill up your terminal buffer (it uses a separate buffer). You will need to pipe stderr to stdout, using the redirection 2>&1. (CCMake is a terminal UI, separate package)

For example, cmake .. 2>&1 | less or ccmake .. and then c to run configure

If you want to hide other output, i.e. detection info, you can pipe stdout to null (cmake .. 2>&1 >/dev/null).

To show only warnings/only errors (the whole message text after it), or showing only one, is hard to do, because they can contain an empty blank line for example, and aren't always as neat as those two errors.

tutacat
  • 70
0

You can, but you must write some basic control logic for each target.

So your example would look like this:

cmake_minimum_required(VERSION 3.6)
project(test)
if(TARGET foo)
    set_property(TARGET foo PROPERTY PROP1 TRUE)
else()
    message(FATAL_ERROR "Target foo does not exist.")
endif()
if(TARGET bar)
    set_property(TARGET bar PROPERTY PROP2 TRUE)
else()
    message(FATAL_ERROR "Target bar does not exist.")
endif()

So now the configuration dies on foo and never makes it to the target bar.

enter image description here

0

This was answered many years ago here: https://stackoverflow.com/questions/1511994/how-to-abort-processing-cmakelists-for-current-directory

Using the return() function within the scope of not finding something, it will then go back to the calling function or parent directory.