How to produce a make build that is verbose only on failure - debugging

There are many ways to produce a verbose make command with cmake.
This has been described in many places. (basically cmake; make VERBOSE=1 or set the CMAKE_VERBOSE_MAKEFILE variable).
Verbose here refers to showing the invoked commands and other information on the steps taken by make.
This seems to be an all or nothing setting.
Either you see all the commands or none of the commands,
regardless of the whether the command succeed or not.
A related tool, ctest (for testing) has a very useful options --output-on-failure for which verbosity depends on the particular test being successful;
only showing the screen out for failing tests.
The question is whether cmake has a similar feature regarding giving details only on failure.
That is, for the most part I don't want to see make compilation commands, but when it fails I would like to see what is the exact command that failed with all the options on display.
That is, the question is if there is some setting or command-line option for make or cmake that, in the build step, will print the full issued command (and output) only for commands that failed.
The reason of course is that it gives the opportunity to see the actual compilation flags for the failing step and allows to reproduce the exact command interactively sometimes.
(I use C++, but the question is general I think)

This is not exactly an answer because you only mentioned make, but what you ask is the default behavior of Ninja. It only outputs the command that failed.

Sometimes, when I am too desperate and I cannot understand the error messages I do this:
make -j 10 -k || make VERBOSE=1
So it will compile fast, and if it fails it runs again serially in verbose mode. It is very likely that the first compilation is the one failing.

Related

PVS-Studio: No compilation units were found

I'm using PVS-Studio in docker image based on ubuntu:18.04 for cross-compiling a couple of files with arm-none-eabi-gcc. After doing pvs-studio-analyzer trace -- .test/compile_with_gcc.sh strace_out file is successfully created, it's not empty and contains calls to arm-none-eabi-gcc.
However pvs-studio-analyzer analyze complains that "No compilation units were found". I tried using --compiler arm-none-eabi-gcc key with no success.
Any ideas?
The problem was in my approach to compilation. Instead of using a proper build system, I used a wacky shell script (surely, I thought, using a build system for 3 files is an overkill, shell script won't hurt anybody). And in that script I used grep to redefine one constant in the source - kinda like that: grep -v -i "#define[[:blank:]]\+${define_name}[[:blank:]]" ${project}/src/main/main.c | ~/opt/gcc-arm-none-eabi-8-2018-q4-major/bin/arm-none-eabi-gcc -o main.o -xc
So compiler didn't actually compiled a proper file, it compiled output of grep. So naturally, PVS-Studio wasn't able to analyze it.
TL;DR: Don't use shell scripts as build system.
We have reviewed the stace_out file. It can be handled correctly by the analyzer, if the source files and compilers are located by the absolute path in the stace_out file. We have a suggestion what might help you. You can "wrap" the build command in a call to pvs-studio-analyzer -- trace and pvs-studio-analyzer analyze and place them inside your script (compile_with_gcc.sh). Thus, the script should start with the command:
pvs-studio-analyzer trace --
and end with the command:
pvs-studio-analyzer analyze
This way we will make sure that the build and analysis were started at the same container run. If the proposed method does not help, please describe in more detail, by commands, the process of building the project and running the analyzer. Also tell us whether the container reruns between the build and the formation of strace_out, and the analysis itself.
It would also help us a lot if you ran the pvs-studio-analyzer command with the optional --dump-log flag and provided it to us. An example of a command that can be used to do this:
pvs-studio-analyzer analyze --dump-log ex.log
Also, it seems that it is not possible to quickly solve the problem and it is probably more convenient to continue the conversation via the feedback form on the product website.

How to view commands that `make` executes?

I have a Makefile, which fails at some point, with a git error. How can I view the git command that causes the whole make process to fail? More precisely, I am looking for a list of commands (including the ones that start with #) that I can run on an identical setup, to achieve the same effect as what make does.
I know for a script, instead of #! /bin/bash you would add a flag -x to it, and that would display all the commands before their execution. How do I do the same thing for make?
I am looking for a list of commands (including the ones that start with #) that I can run on an identical setup, to achieve the same effect as what make does.
By default, make echoes all recipe commands it runs, except those prefixed with #. The POSIX specifications for make do not describe a way to override that effect of # (but see below). It is conceivable that your make has an extension for that, but the make implementations you are most likely to be using (GNU make or BSD make, since you seem to assume that your standard shell is bash) do not.
Additionally, in POSIX-conforming make implementations, including the two mentioned above, the special target .SILENT can be used to suppress echoing the commands of some or all targets, and the -s command-line option can be used to suppress echoing for all targets.
You can print recipe commands prefixed with # if you run make with the -n (no-op) flag. That will print the commands for out-of-date targets without running them, except that those prefixed with a + are run even in no-op mode. Commands prefixed with # are included among those printed. Under some circumstances, the fact that most commands are not actually run in this mode can affect the output, but all the cases I can think of at the moment involve recursive make, and I think they are fairly unlikely.
POSIX seems to indicate that -n does not override -s or .SILENT, so if you have to deal with those then you may have no alternative but to modify your makefile. If you happen to be using GNU make, however, you will find that -n does override .SILENT and -s in that implementation. The same may be true of other makes.

What is the difference between cmdline options --trace and --debug-output in cmake?

Does the "--trace" option show more details than "--debug-output" does? cmake -h does not explain much.
The documentation seems to be pretty clear on that:
For --debug-output it
prints extra information during the cmake run like stack traces with message(SEND_ERROR) calls.
And --trace flag simply makes CMake to print every command it is executing. It helps to see how loops or macros are executed, because commands are outputted in flattened form.

How to just see a full command that gives error in GNU makefile

When I'm compiling something, it gives errors like this:
$ make
CC test/hello.o
test/hello.c:37:29: fatal error: this/is/hard/to/find.h: No such file or directory
Then, is it possible to see the full command of CC (with all the options) by just giving an proper option to make without modifying Makefile?
Usually when a Makefile is set up to print summary lines like this instead of the full command, they also define a VERBOSE or QUIET variable to control that behavior. You might try just running make as make VERBOSE=1, but if that doesn't work you'll have to check the Makefile to see if it supports verbose output through some other mechanism, or post some of your Makefile for us to see.
Alternatively, you could use something like ElectricAccelerator, a high-performance replacement for GNU make that, among other features, can produce an XML-marked-up version of your build log, including all the command-lines for every command invoked, even if the Makefile normally only prints summaries like you've shown.
(Disclaimer: I'm the architect and lead developer of ElectricAccelerator)

invoke make from build

I'd like to simplify the workflow so that rather than issuing these commands
$ make program_unittest
... output of $MAKE ...
$ ./program_unittest args
I could have my program automatically attempt to compile itself (if the source has been updated) when it is run, so that I do not have to go back and run make myself.
Here's what I'm thinking: My unit test build should first check if there is a makefile in the directory it's in, and if so, fork and exec make with the target corresponding to itself. If make determines "nothing to be done", it will continue on its way (running the unit-tests). However, if make actually performs a compilation, one of two things may happen. gcc (invoked by make) might be able to overwrite the build (an older version of which is already running) during compilation, in which case I can then perhaps exec it. If my system does not permit gcc to overwrite the program which is in use, then I have to quit the program before running make.
So this has become quite involved already. Are there perhaps more elegant solutions? Maybe I could use a bash script? How do I ascertain if make issued compilation commands or not?
Why not have make run the unit tests?

Resources