On Fri, May 21, 2010 at 10:47 AM, Martin d'Anjou <[email protected]> wrote: > I came up with this makefile to ensure targets were not defined multiple > times when building them on the fly: ... > define rule > ifndef $(basename $(notdir $1))_SENTINEL > $(info Rule not defined. Defining it.) > $(basename $(notdir $1))_SENTINEL:=rule_defined > $1: $2 > echo Built $1 $3 > else > $(info Sentinel "$(basename $(notdir $1))_SENTINEL" already defined as > $($(basename $(notdir $1))_SENTINEL)) > endif > endef > > $(info Call 1) > $(eval $(call rule,file1.v,file1.c,1)) ... > In the end, I get the desired effect (redefinitions of the same rule don't > occur), but both the "then" and the "else" branches be taken at the same > time. Is this a problem?
Yes, it's a problem lots of people using $(eval) screw up on. To quote the description of $(eval) in the info pages: ------- It's important to realize that the `eval' argument is expanded _twice_; first by the `eval' function, then the results of that expansion are expanded again when they are parsed as makefile syntax. This means you may need to provide extra levels of escaping for "$" characters when using `eval'. The `value' function (*note Value Function::) can sometimes be useful in these situations, to circumvent unwanted expansions. ------- So a round of variable and function expansion is done on 'rule' *BEFORE* it is interpreted as make syntax, when 'ifndef' is just a piece of text and not a directive. If you want your uses of $(eval) to work correctly and reliably, you must consider which pass each variable and function reference should be expanded. You want those $(info) expansions to take place in the second pass, after the make syntax has been recognized, so they should be written as $$(info whatever). Or use include files instead of $(eval) to avoid creating something you can't maintain. Philip Guenther _______________________________________________ Help-make mailing list [email protected] http://lists.gnu.org/mailman/listinfo/help-make
