How do you abort on shell command errors in makefiles?

I'm trying to write a makefile to package up some PHP scripts. I would also like it to check for syntax errors (using the built in php lint tool) before building the final zip file, to prevent any accidental errors slipping in.

So far I have

all: dist clean: rm -f dist: clean for i in `find . -name "*.php"`; do php -l $$i; done zip -r src -x "*/.*" "*/tests*"

This works, but if there is a PHP error I would like it to break and not continue building the zip file (for obvious reasons). Currently they may just get lost in the pages of output from successful lint runs and the zip file.

Am I going about this the right way? Should I be using a make loop rather than a shell loop? How to you get make to abort on shell command errors?


You can do something like this:

for i in `find . -name "*.php"`; do \ php -l $$i; \ if [ $$? -ne 0 ] ; then exit 42 ; fi \ done


The shell for loop in your dist recipe is hiding the exit status of php -l from make, so it doesn't know to exit. Mat's answer shows how to fix that by having the shell command exit on error.

The shell loop could be avoided entirely like this:

all: dist clean: rm -f LINT_TARGETS := $(addprefix lint-,$(shell find . -name "*.php")) .PHONY: $(LINT_TARGETS) $(LINT_TARGETS):lint-%:% php -l $< dist: clean $(LINT_TARGETS) zip -r src -x "*/.*" "*/tests*"

Now there's a phony target with a static pattern rule to run each of the php -l commands. If any of them fails, the dist recipe will not run. This is arguably harder to read than a shell loop, but it means that a) the error message from make itself will finger the problematic file for you and b) with make -j you can have multithreaded lint checks :-)

人吐槽 人点赞



用户名: 密码:
验证码: 匿名发表


查看评论:How do you abort on shell command errors in makefiles?