[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: ifdef around define to remove overriding commands for target warnin
Re: ifdef around define to remove overriding commands for target warning
Fri, 21 May 2010 11:37:49 -0700
On Fri, May 21, 2010 at 10:47 AM, Martin d'Anjou <address@hidden> 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
> $(info Sentinel "$(basename $(notdir $1))_SENTINEL" already defined as
> $($(basename $(notdir $1))_SENTINEL))
> $(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
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
Or use include files instead of $(eval) to avoid creating something
you can't maintain.