[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ifdef around define to remove overriding commands for target warnin

From: Philip Guenther
Subject: Re: ifdef around define to remove overriding commands for target warning
Date: 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
> 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

Or use include files instead of $(eval) to avoid creating something
you can't maintain.

Philip Guenther

reply via email to

[Prev in Thread] Current Thread [Next in Thread]