Mon 06 Oct 2014 06:49:39 AM UTC, original submission:
I'm trying to implement prerequisite feedback via environment backpropagation.
Here's "test.1":
( http://pastebin.com/ZiEJpEhr )
--- [ test.1 ] ---
:: T=a b c d e
:: .PHONY: $(T)
:: $(T):
:: $(if $($(@)_BRINGBACK),$(eval $($(@)_BRINGBACK)))
:: $(if $($(@)_BRINGBACK),@echo '>' $@':' $(@)_BRINGBACK = $($(@)_BRINGBACK))
:: $(if $(LDFLAGS),@echo '>' $@':' LDFLAGS = $(LDFLAGS))
:: @echo '>' $@':'$(if $+, $+)$(if $|, '|' $|)
::
:: .DEFAULT: a
:: a: b | c
:: b: d
:: c: e
:: e_BRINGBACK = LDFLAGS += -lz
--- [ test.1 ] ---
--- [ test.1 output ] ---
:: d:
:: b: d
:: e: e_BRINGBACK = LDFLAGS += -lz
:: e: LDFLAGS = -lz
:: e:
:: c: LDFLAGS = -lz
:: c: e
:: a: LDFLAGS = -lz
:: a: b | c
--- [ test.1 output ] ---
Append global environment variable to "test.1" and name it "test.2":
( http://pastebin.com/JqUN36ZP )
--- [ test.2 ] ---
:: LDFLAGS = -lm
--- [ test.2 ] ---
--- [ test.2 output ] ---
:: d: LDFLAGS = -lm
:: d:
:: b: LDFLAGS = -lm
:: b: d
:: e: e_BRINGBACK = LDFLAGS += -lz
:: e: LDFLAGS = -lm -lz
:: e:
:: c: LDFLAGS = -lm -lz
:: c: e
:: a: LDFLAGS = -lm -lz
:: a: b | c
--- [ test.2 output ] ---
Append target environment variable to "test.1" and name it "test.3":
( http://pastebin.com/z9L17eaJ )
--- [ test.3 ] ---
:: a: LDFLAGS = -lm
--- [ test.3 ] ---
--- [ test.3 output ] ---
:: d: LDFLAGS = -lm
:: d:
:: b: LDFLAGS = -lm
:: b: d
:: e: e_BRINGBACK = LDFLAGS += -lz
:: e: LDFLAGS = -lm
:: e:
:: c: LDFLAGS = -lm
:: c: e
:: a: LDFLAGS = -lm
:: a: b | c
--- [ test.3 output ] ---
Append slightly different target environment variable to "test.1" and name it "test.4":
( http://pastebin.com/jGaz8H8t )
--- [ test.4 ] ---
:: a: LDFLAGS += -lm
--- [ test.4 ] ---
--- [ test.4 output ] ---
:: d: LDFLAGS = -lm
:: d:
:: b: LDFLAGS = -lm
:: b: d
:: e: e_BRINGBACK = LDFLAGS += -lz
:: e: LDFLAGS = -lm -lz -lm
:: e:
:: c: LDFLAGS = -lm -lz -lm
:: c: e
:: a: LDFLAGS = -lm -lz -lm
:: a: b | c
--- [ test.4 output ] ---
Append target variable and global variable to "test.4" and name it "test.5":
( http://pastebin.com/5hv5jzFq )
--- [ test.5 ] ---
:: LDFLAGS += -lbz2
--- [ test.5 ] ---
--- [ test.5 output ] ---
:: d: LDFLAGS = -lbz2 -lm
:: d:
:: b: LDFLAGS = -lbz2 -lm
:: b: d
:: e: e_BRINGBACK = LDFLAGS += -lz
:: e: LDFLAGS = -lm -lz -lm
:: e:
:: c: LDFLAGS = -lm -lz -lm
:: c: e
:: a: LDFLAGS = -lm -lz -lm
:: a: b | c
--- [ test.5 output ] ---
I've rebuilt make with DEB_BUILD_OPTIONS="nostrip noopt" and debugged with file "test.5".
I've discovered two moments which determine such behavior:
1) appending to variable in "$(eval ...)" takes only first value in chain.
e.g.:
LDFLAGS defined in global context as "LDFLAGS += 1" and in target "A" as "LDFLAGS += 2", then actual value for "A" and all it's prerequisites will be "1 2".
Calling "$(eval LDFLAGS += 3)" in recipe of target "A" or any prerequisite defines "LDFLAGS" as "2 3".
2) variable assignment during "$(eval ...)" in recipe sets new value in top-most variable without setting "variable.recursive = 0".
i.e.:
LDFLAGS after "$(eval ...)" equals "2 3" and defined in global context, but it's still recursive, that's why LDFLAGS is equal "2 3 2".
Imho, there're several points to fix:
1) variable manipulations during "$(eval)" in recipe context may be handled in same way as variable assignment in recipes (i.e. "A: LDFLAGS += X");
2) variable assignment during "$(eval)" may grab entire value instead of first non-empty value in chain;
3) variable's flag "recursive" may be set to "0" if value was overwritten.
PS: this bug is reproducible in 3.81 too.
--
SY,
Konstantin Demin
|