Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Makefile : --ignore-errors vs --keep-going

I was going through Makefile documentation, I am not clear of the difference between --ignore-errors and --keep-going.

Can someone please highlight the difference between the two? To me, both seem to continue after an error has occured.

Though its not clear from documentation, but --ignore-errors could have recipe-level scope and if one recipe line has failed, next one will continue to execute. --keep-going may have target-level scope and if any target recipe fails, the recipe execution ends there, but other prerequisites/targets will still be attempted to make. This is just a possible perception and need clarification on this.

like image 603
Naveen Avatar asked Oct 29 '18 05:10

Naveen


People also ask

How do I ignore errors in makefile?

To ignore errors in a recipe line, write a ' - ' at the beginning of the line's text (after the initial tab). The ' - ' is discarded before the line is passed to the shell for execution. This causes make to continue even if rm is unable to remove a file.

What is $$ in makefile?

Commands and executionIf you want a string to have a dollar sign, you can use $$ . This is how to use a shell variable in bash or sh . Note the differences between Makefile variables and Shell variables in this next example.

What is Gmake in Linux?

gmake (GNU make - called simply make on linux systems) is a tool to help you build a program from its source. For our trivial Zoo program its possible to completely build the Zoo.exe from scratch in a few seconds.

What does all do in makefile?

This means that when you do a "make all", make always thinks that it needs to build it, and so executes all the commands for that target. Those commands will typically be ones that build all the end-products that the makefile knows about, but it could do anything.


1 Answers

https://www.gnu.org/software/make/manual/make.html#Errors

Sometimes the failure of a certain recipe line does not indicate a problem. For example, you may use the mkdir command to ensure that a directory exists. If the directory already exists, mkdir will report an error, but you probably want make to continue regardless.

To ignore errors in a recipe line, write a - at the beginning of the line’s text (after the initial tab). The - is discarded before the line is passed to the shell for execution.

For example,

clean:
        -rm -f *.o

This causes make to continue even if rm is unable to remove a file.

When you run make with the -i or --ignore-errors flag, errors are ignored in all recipes of all rules. A rule in the makefile for the special target .IGNORE has the same effect, if there are no prerequisites. These ways of ignoring errors are obsolete because - is more flexible.

In other words, make --ignore-errors behaves like there is a - in front of all commands.

When errors are to be ignored, because of either a - or the -i flag, make treats an error return just like success, except that it prints out a message that tells you the status code the shell exited with, and says that the error has been ignored.

When an error happens that make has not been told to ignore, it implies that the current target cannot be correctly remade, and neither can any other that depends on it either directly or indirectly. No further recipes will be executed for these targets, since their preconditions have not been achieved.

Normally make gives up immediately in this circumstance, returning a nonzero status. However, if the -k or --keep-going flag is specified, make continues to consider the other prerequisites of the pending targets, remaking them if necessary, before it gives up and returns nonzero status. For example, after an error in compiling one object file, make -k will continue compiling other object files even though it already knows that linking them will be impossible. See Summary of Options.

The usual behavior assumes that your purpose is to get the specified targets up to date; once make learns that this is impossible, it might as well report the failure immediately. The -k option says that the real purpose is to test as many of the changes made in the program as possible, perhaps to find several independent problems so that you can correct them all before the next attempt to compile. This is why Emacs’ compile command passes the -k flag by default.

Let's take this example:

target: intermediate-1 intermediate-2 intermediate-3
        cat intermediate-1 intermediate-2 intermediate-3 > target

intermediate-1:
        echo "oh no, I'm failing!"
        false

intermediate-2:
        echo 'hello' > intermediate-2

intermediate-3:
        echo 'world' > intermediate-3

Normally when you run make target (and none of the files exist yet), it will first try to make intermediate-1. That target fails because one of the associated commands (false) returns a non-zero exit status. make then immediately gives up and does not even look at intermediate-2 or intermediate-3.

However, with make --keep-going target, it will note the failure of intermediate-1, but keep on going to make intermediate-2 and intermediate-3, which succeeds (creating files containing "hello" and "world", respectively).

In the end it still gives up and reports a failure to make target, but it has tried to create all intermediate targets, even ones it knows won't be used in this run of make because another prerequisite already failed.

If you use both flags (make --ignore-errors --keep-going), then --keep-going is effectively ignored. --keep-going only affects how make behaves when it encounters an error in an intermediate target, but --ignore-errors means make will never encounter an error.

like image 200
melpomene Avatar answered Sep 30 '22 18:09

melpomene