Sun 28 Dec 2008 07:47:56 AM UTC, comment #1:
The reason this happens is because pattern-specific variables are treated very differently from target-specific variables, internally. With target-specific variables there is an actual target and the variables are kept and expanded with reference to that target. Since an explicit target is stated, even if that target is not known already we can create one to hook these variables to when the makefile is read in.
With pattern-specific variables there is no known target at the time the pattern variable is defined, so pattern variables are simply kept as a list of potential variable settings. They are not resolved when the makefile is read in, because there's no target to "hook" them to. They are resolved when the target is to be built: at that time all the pattern-specific variable patterns are matched, one at a time, to the target and if it matches the expansion occurs. Obviously that comes in the second phase of the build, after the makefiles have all been read in (and, in your example, the variable $(v) has been reset).
It's potentially conceivable that all the pattern-specific variables with the exact same pattern could be treated as target-specific variables are, and the variable settings for that pattern can be combined into a "group". However, even that would not be 100% accurate; suppose you had two patterns "%.bar" and "foo%.bar", then with a target of "foobaz.bar" you could reasonably expect the pattern-specific variables to be handled as if they were target-specific variables for "foobaz.bar"... but there's really no way to do that.
This behavior is actually quite tricky to get right: combining :=, +=, inheritance, etc.
I'll leave this open as an enhancement request.
|
Sun 21 Dec 2008 10:20:54 AM UTC, original submission:
Consider this makefile:
v := two
%.bar: var := one
%.bar: var += $(v)
%.bar: var += three
v :=
%.bar: ; @echo $(var)
all: foo.bar
When used with 3.81, it prints 'one three' while I would expect it to print 'one two three'. If I change pattern-specific to target-specific assignment, it works as expected:
foo.bar: var := one
foo.bar: var += $(v)
foo.bar: var += three
The workaround for this problem is to use temporary variable:
tmp := one
tmp += $(v)
tmp += three
%.bar: var := $(tmp)
|