Make: super ignore errors - makefile

If I want to run a command that may or may not work, depending on the situation, I add a dash
make-rule:
-command that may fail
however, when this command fails, I get a message that the entire recipe failed.
How do I flag the command as totally optional, such that even if it fails, make just notes that it failed, but not that the over-all recipe failed?
(this saves time having to carefully read the make messages, if I don't get informed that the entire recipe failed)

It's a bit manual, but you can use an or-sequence in the recipe, as in:
make-rule:
command that may fail || echo "command failed with status $$?"
since echo will succeed, make will consider that the whole line is OK, but you still get your error message in case of problem.

Related

What does each field in a typical sh error message mean? Ex. "sh: 1: ipconfig: not found"

I have been receiving Shell error messages, typically due to a bad command, etc., but have been unable to debug the cause of these messages due to not understanding the information being provided.
I have been looking for documentation, but have been unable to find any regarding the format of an sh error message.
Example:
If I use the following command, it will fail, due to no 'ipconfig' command being available:
$ sh -c "ipconfig"
sh: 1: ipconfig: not found
What I'd like to understand is what each 'field' in that message pertains to? I assume it is:
[interpreter]: [???]: [command]: [error related to command]
I can't for the life of me determine what the number refers to, and I can't be sure if my understanding of the other fields is accurate.
Context:
I am debugging a Python2.7 pytest script used for automation testing, and there are numerous points where this script is executing shell commands. However, the output I receive is:
(32512, 'sh: 2: 2: not found')
I know that function being used to execute the shell script returns a tuple with status code and output. I know that that status code is essentially 'command not found', and the error message is also stating that. Another function is returning a string which is used for this command, and I assume what is happening is that somewhere along the way, a bad argument must have been passed and now the script is attempting to execute, what would basically be sh -c "2". I can't be sure though, as these are a lot of assumptions I'm making from a limited understanding of this error message.
If anyone could please enlighten me as to what the fields in this error ACTUALLY mean I'd be forever grateful!!

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

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.

How to save and return exit code in makefile target

I have a make target that looks something like this:
.PHONY: run-my-test
run-my-test: all
run_test_suite.sh --all --log-to-file
post_process_logs.sh
If a test case fails, the exit code of run_test_suite.sh will cause Make to not continue with running post_process_logs.sh. This is a problem, because i want to get the processed logs even for failed tests. How should i update my target to do this?
I've thought of saving the exit code somehow and perhaps exit with it in the end of the target definition. Or do I split the calls up into separate targets?
I can add that I'm pretty much forced to do this from Make because of how our build system works. And I would prefer not having to add more targets as the make files tend to be cluttered with these as it is.
If you want the build to fail after running post_process_logs.sh, put both commands in the same entry.
.PHONY: run-my-test
run-my-test: all
run_test_suite.sh --all --log-to-file; \
e=$$?; \
post_process_logs.sh; \
exit $$e
The exit status of run_test_suite.sh is saved in the shell variable e, which is used as the argument to exit after post_process_logs.sh to set the exit status of the overall command.

Make ignore errors: what is the difference between -i and -k

I want make to continue even if a dependency's build fails. I usually use -i to accomplish this. A colleague of mine said he uses -k. Indeed, this stack overflow question has an answer for each:
Make: how to continue after a command fails?
Is there a difference between these two options?
Here's what the make man page says for these two options:
-i, --ignore-errors
Ignore all errors in commands executed to remake files.
-k, --keep-going
Continue as much as possible after an error. While the
target that failed, and those that depend on it, cannot be
remade, the other dependencies of these targets can be
processed all the same.
What -k describes is what I think -i does. I'm sure I'm missing something: can someone help me understand the difference?
Consider this makefile:
all: fail success
all success:
#echo $#
fail:
exit 1
#echo $#
Now run with the two flags:
$ make -i
exit 1
make: [Makefile:7: fail] Error 1 (ignored)
fail
success
all
This flag caused make to pretend that a specific recipe command succeeded, even though it failed. Thus the all target is still run, because make believes that the fail target actually succeeded. It's equivalent to adding a - at the beginning of every recipe line.
As opposed to:
$ make -k
exit 1
make: *** [Makek:7: fail] Error 1
success
make: Target 'all' not remade because of errors.
Here, make knows the fail target was not built. success is run because of -k: it doesn't depend on fail. However, all is not built because it does depend on fail.
I've never really needed -i; it seems dangerous to me.
On the other hand, I use -k almost by default.

How to know error has happened when using make -k

I want to log every error on building code.
so I can use -k to make it keep-going even error happened.
However, could I know some error has happened,
and it is -k to make it continue?
I know I can check some pattern error message like make: ***.
But I still wondering if I can have some message in log like:
"error happened, keep-going to make" when I have -k.
Thanks.
make reports errors on its output/error for human readers. Other computer programs can check its exit status, which should be non-zero if any error has occurred. If you're calling make from a shell script, you could do something similar to
make -k || echo "BAD: ERROR(S)"
except change echo to something that's actually useful for you. Other ways to call make will have similar options.

Resources