Sat 30 Dec 2006 02:03:43 PM UTC, original submission:
I think I've found in GNUmake 3.81 a hard-to-realize bug. This bug causes $(error ) function unable to stop the whole make process. I encountered this bug recently when I'm developing an auto-building system based on GNUmake(called GnumakeUniproc), and I have isolate the smallest makefile(filename: eGmu.makefile, 30 effective lines, see the attached file) that can reproduce this problem.
Be aware, in order to see this bug, you have to `rm _MainPrjBuildStart.gmu.ckt' before invoking my makefile, -- honestly, you just have to do it.
Output from make 3.81:
===============
[chj @vchjsuse101 ~/test/clear381]
$ make381 -f eGmu.makefile
make381[1]: Entering directory `/home/chj/test/clear381'
_SubprjsAttr.gmu.mki:1: *** ====== Hey! you should stop here! [./_MakeSubPrjs.gmu.mk] ======. Stop.
make381[1]: Leaving directory `/home/chj/test/clear381'
_SubprjsAttr.gmu.mki:1: *** ====== Hey! you should stop here! [eGmu.makefile] ======. Stop.
===============
You can see that `` <some-makefile>:<line-number>: *** <error message>. Stop.'' appears more than once, which is not the correct behavior.
GNUmake 3.80 does not have this bug however. Output from make 3.80:
===================
[chj @vchjsuse101 ~/test/clear381]
$ make380 -f eGmu.makefile
make[1]: Entering directory `/home/chj/test/clear381'
_SubprjsAttr.gmu.mki:1: *** ====== Hey! you should stop here! [./_MakeSubPrjs.gmu.mk] ======. Stop.
make[1]: Leaving directory `/home/chj/test/clear381'
make: *** [_SubprjsMade.gmu.ckt] Error 2
===================
My testing environment:
- SuSE Linux 10.1 with stock make 3.80.
- And I build make 3.81 from official source on SuSE Linux 10.1 with command ./configure && make .
###############################################################
Finally, I also post my eGmu.makefile here:
================================================
_IsP1OlderThanP2 = $(if $(wildcard $1),$(shell (if [ $1 -ot $2 ];then echo -n '1';fi)),1)
# If file $1 not exist or older than $2, 1 is returned, else null is returned.
# If $2 does not exist, result is undetermined.
_IsOlderThanPrjStart = $(call _IsP1OlderThanP2,$1,$(_p_MainPrjStart))
_ClearFile = echo -n "" > $(1)
gmu_Gd_PRJ_GMUTMP = .
_StartupSignatureFile = _MainPrjBuildStart.gmu.ckt
ifeq ($(MAKELEVEL),0)
export _p_MainPrjStart = $(CURDIR)/$(_StartupSignatureFile)
# Important! User should first delete it before invoking the makefile of the main-project!
#Otherwise, the build can be incomplete.
ifeq (,$(wildcard $(_p_MainPrjStart))) # Do these only if the main-prj-start signature does not exist.
# The first thing here is to create the main-prj-start signature, so that the code
# in this if/endif will only execute once during one whole build process.
_temp := $(shell if (echo -n "" > $(_p_MainPrjStart)) ; then echo -n ''; \
else echo __GMU_ex_ERROR; fi; )
ifneq (,$(_temp))
$(error !GMU!Error: Cannot create start-up signature file($(_StartupSignatureFile)) in current dir)
endif
endif # ifeq (,$(wildcard $(_p_MainPrjStart)))
endif # ifeq ($(MAKELEVEL),0)
_p_mki_SubprjAttr = $(gmu_Gd_PRJ_GMUTMP)/_SubprjsAttr.gmu.mki
_p_SubprjsAttrMade = $(gmu_Gd_PRJ_GMUTMP)/_SubprjsAttrMade.gmu.ckt
_p_mk_MakeSubPrjs = $(gmu_Gd_PRJ_GMUTMP)/_MakeSubPrjs.gmu.mk
_p_SubprjsMade = $(gmu_Gd_PRJ_GMUTMP)/_SubprjsMade.gmu.ckt
-include $(_p_SubprjsMade)
$(_p_SubprjsMade): $(_p_MainPrjStart)
@$(call _ClearFile,$(_p_mk_MakeSubPrjs))
@echo -e "include $(_p_mki_SubprjAttr)\n" >> $(_p_mk_MakeSubPrjs)
@${MAKE} -f $(_p_mk_MakeSubPrjs)
@echo -n "" > $@
ifeq ($(call _IsOlderThanPrjStart,$(_p_SubprjsAttrMade)),1)
# $(warning %%%%%%%%%%%%%%%%% [$(MAKELEVEL)] [$(MAKE_RESTARTS)] %%%%%%%%%%%%%%%)
-include $(_p_SubprjsAttrMade)
else
# $(warning +++++++++++++++++ [$(MAKELEVEL)] [$(MAKE_RESTARTS)] +++++++++++++++)
include $(_p_mki_SubprjAttr)
endif
$(_p_SubprjsAttrMade): $(_p_MainPrjStart)
@$(call _ClearFile,$(_p_mki_SubprjAttr))
@echo "\$$(error ====== Hey! you should stop here! [\$$(firstword \$$(MAKEFILE_LIST))] ======)" >> $(_p_mki_SubprjAttr)
@echo -n "" > $@ # touch it
================================================
|