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 output.zip dist: clean for i in `find . -name "*.php"`; do php -l $$i; done zip -r output.zip 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?

Answer1:

You can do something like this:

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

Answer2:

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 output.zip LINT_TARGETS := $(addprefix lint-,$(shell find . -name "*.php")) .PHONY: $(LINT_TARGETS) $(LINT_TARGETS):lint-%:% php -l $< dist: clean $(LINT_TARGETS) zip -r output.zip 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 :-)

人吐槽 人点赞

Recommend

Comment

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

你可以使用这些语言

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