all: start doSomeMagicToChangeRegFile end
start: $(OBJDIR)
@$(TOUCH) build/$(CONFIG)/$(CONFIG).reg || exit
@$(MD5SUM) build/$(CONFIG)/$(CONFIG).reg > build/$(CONFIG)/MD5SUM_REG_BEGIN
...........
end: $(APPL_OBJ)
...........
@$(MD5SUM) build/$(CONFIG)/$(CONFIG).reg > build/$(CONFIG)/MD5SUM_REG_END
@$(HEAD) build/$(CONFIG)/MD5SUM_REG_BEGIN
@$(HEAD) build/$(CONFIG)/MD5SUM_REG_END
ifneq ($(HEAD) build/$(CONFIG)/MD5SUM_REG_BEGIN,$(HEAD) build/$(CONFIG)/MD5SUM_REG_END)
@$(ECHO) "REBUILD"
@$(RM) -fr build/$(CONFIG)/$(CONFIG)/*.o*
@$(MAKE) -i $(CONFIG)
else
@$(ECHO) "DONE"
endif
This gnu make file builds some code with the Keil compiler and creates a reg file within this context. The code should be recompiled until the reg file doesn't change any more. There is a md5 hash calculation at the start and at the end. Both hashs are compared at the end. But this check results in an infinite loop. The evaluation of the ifneq conditional doesn't seem to work. The result of @$(HEAD) build/$(CONFIG)/MD5SUM_REG_BEGIN
and @$(HEAD) build/$(CONFIG)/MD5SUM_REG_END
are correct, but apparently not in the conditional. Why?
答案 0 :(得分:0)
You're confused about a few things. First ifeq
/ifneq
are string comparison functions: they compare the strings $(HEAD) build/$(CONFIG)/MD5SUM_REG_BEGIN
and $(HEAD) build/$(CONFIG)/MD5SUM_REG_END
, which by definition will never be equal so the ifneq
is always true. ifeq
/ifneq
do not compare the contents of files.
Second, the make processor statements like include
, ifeq
, etc. are all parsed as the makefile is read in, long before make starts to actually run any rules. So at the time the ifneq
is parsed none of the recipe has been invoked.
If you want a conditional that runs as part of the recipe, then you have to actually make it part of the recipe and use shell conditionals, not make conditionals.
ETA Something like this:
RMAKE = $(MAKE)
end: $(APPL_OBJ)
...........
@$(MD5SUM) build/$(CONFIG)/$(CONFIG).reg > build/$(CONFIG)/MD5SUM_REG_END
@$(HEAD) build/$(CONFIG)/MD5SUM_REG_BEGIN
@$(HEAD) build/$(CONFIG)/MD5SUM_REG_END
@if [ `$(HEAD) build/$(CONFIG)/MD5SUM_REG_BEGIN` != `$(HEAD) build/$(CONFIG)/MD5SUM_REG_END` ]; then \
$(ECHO) "REBUILD"; \
$(RM) -fr build/$(CONFIG)/$(CONFIG)/*.o*; \
$(RMAKE) -i $(CONFIG); \
else \
$(ECHO) "DONE"; \
fi
The RMAKE
trick is needed if you ever want to run make -n
and have it do the right thing.
@triplee is right, though, using @
before all these lines is a bad idea. It makes debugging your makefiles super-annoying. At the very least you should not add them until after your makefile is fully developed and working.