原文地址:http://www.crifan.com/makefile_not_stop_on_error/
【问题】
写了个makefile:
#goto every sub foler(single book)'s src dir to do 'make xxx' action clean clean_all clean_release all release release_copy: @echo "Current path="`pwd`; @echo "LS_OUTPUT="$(LS_OUTPUT); for each_item in $(LS_OUTPUT); \ do \ if [ -d $$each_item/src ]; then \ cd $$each_item/src && \ echo `pwd` && \ if [ -f Makefile ]; then \ make $@; \ fi; \ cd ../..; \ fi; \ done;
然后对应的src中的子makefile中,是去执行对应的动作。
比如执行make release_copy,其会对于每一个子文件夹去执行此make release_copy。
现在问题是,对于某个子文件夹下面,单独执行make release_copy,是会出现错误,并且makefile会正常的停止继续执行的。
但是对于顶层的去执行makefile release_copy的话,其虽然也同样显示错误,但是却会继续执行后续的动作。
【解决过程】
1。默认makefile遇到错误就会停止,对于此处却失效了。所以很是悲剧。
2.到网上找资料,找到这个9.6 Testing the Compilation of a Program,其中倒是有关于想要在出错的时候,仍然让其继续运行,有解释,即用-k参数。
但是我此处就是已经有了此现象了,想不让其遇到错误却继续运行,但是却没有相应的参数可以用。
3.后来找到:Re: question on makefile: not stop after compling error,其指出了原因,并给出了解决方法,
那是因为对于子makefile执行的结果,没有判断返回值,所以导致子makefile错误的时候,其实是停止了,然后返回错误值了,但是上层的makefile却没有判断返回值,导致会继续执行,所以表现形式就是虽然makefile执行过程中出错,但是却还是继续运行。
然后照葫芦画瓢去改为:
#goto every sub foler(single book)'s src dir to do 'make xxx' action clean clean_all clean_release all release release_copy: @echo "Current path="`pwd`; @echo "LS_OUTPUT="$(LS_OUTPUT); for each_item in $(LS_OUTPUT); \ do {\ if [ -d $$each_item/src ]; then \ cd $$each_item/src && \ echo `pwd` && \ if [ -f Makefile ]; then \ make $@; \ fi; \ cd ../..; \ fi; \ } || exit "$$?";\ done;
结果问题依旧,遇到错误,还是继续运行。
然后注意到,是需要在对子makefile返回值做判断,所以又改为:
#goto every sub foler(single book)'s src dir to do 'make xxx' action clean clean_all clean_release all release release_copy: @echo "Current path="`pwd`; @echo "LS_OUTPUT="$(LS_OUTPUT); for each_item in $(LS_OUTPUT); \ do \ if [ -d $$each_item/src ]; then \ cd $$each_item/src && \ echo `pwd` && \ if [ -f Makefile ]; then \ make $@ || exit "$$?"; \ fi; \ cd ../..; \ fi; \ done;
如此,就可以了,遇到错误,就会停止了。
【总结】
makefile执行错误,结果还会继续执行,此处是由于是上层makefile调用下层子makefile,子makefile执行出错,停止返回到上层后,上层没有判断返回值,导致还是会继续执行。
解决办法是,对于子makefile调用,判断返回值,
比如将:
make $@;
改为:
make $@ || exit "$$?";
这样make执行错误返回值为非0,然后就可以执行后面的exit而退出了。