Hanans
Hanans

Reputation: 103

how to force make to quit after external script error but not after compilation error

I have a C project built with gnu-make.

as part of the build process I run some python scripts. the scripts may return an error (with sys.exit(1) for example).

I wish to stop the build process immediately after an error returned from a python script but not after a "normal" compilation error.

when I run make with -k, it keeps going after an error from python or compilation, and without it it stops on the first error in all cases...

any way to accomplish what I'm looking for?

Thanks.

Upvotes: 0

Views: 611

Answers (2)

Renaud Pacalet
Renaud Pacalet

Reputation: 29040

From GNU make manual:

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.

So, just put a - on from of the commands for which you want make to ignore errors, and not on front of the others.

Upvotes: 0

John Bollinger
John Bollinger

Reputation: 180201

any way to accomplish what I'm looking for?

Yes.

make does not distinguish between different commands in recipes. It just submits them to the shell for execution, and takes note of their exit status to determine how to proceed afterward. Therefore, if there is any command in any recipe whose failure should cause make to stop, then you must not use the -k option.

If you do not use -k, then the problem becomes how to have make not stop when it encounters an error you want it to ignore. That's (conceptually) easy: just ensure that those commands cannot fail. You can do that by appending || : to the end of the command, so that if the main command fails, the : command -- which does nothing and always succeeds -- will run and provide the overall exit status:

foo.o: foo.c
    $(CC) -o $@ $(CPPFLAGS) $(CFLAGS) $< || :

Note well that this approach requires you to provide your own rules wherever you want to avoid stopping on error. Make's built-in rules will not exhibit the same behavior.

You can even make this configurable, and I recommend you do so:

# Stop on error (unless -k is in effect):
# ON_ERROR =
#
# Do not stop on (most) errors: 
ON_ERROR = || :

foo.o: foo.c
    $(CC) -o $@ $(CPPFLAGS) $(CFLAGS) $< $(ON_ERROR)

bar.o: bar.c
    $(CC) -o $@ $(CPPFLAGS) $(CFLAGS) $< $(ON_ERROR)

baz.o: baz.c
    $(CC) -o $@ $(CPPFLAGS) $(CFLAGS) $< $(ON_ERROR)

That way you have one place in which you can turn all the error suppression on or off.

Upvotes: 1

Related Questions