#763768 strange behavior of gnu make

#763768#5
Date:
2014-10-02 14:32:54 UTC
From:
To:
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 ] ---
--- [ 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 ] --- --- [ test.2 output ] --- Works well. 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 ] --- --- [ test.3 output ] --- Not so good, as you may see. And finally, 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 ] --- --- [ test.4 output ] --- This completely breaks my mind. Questions: 1. why LDFLAGS is not modified in #3? 2. why LDFLAGS is messed up in #4? Thank you.
#763768#10
Date:
2014-10-03 05:27:10 UTC
From:
To:
Furthermore, here's detailed test.

Append target variable and global variable to "test.1" and name it "test.5":
{ http://pastebin.com/5hv5jzFq }
--- [ test.5 ] ---
a: LDFLAGS += -lm
LDFLAGS += -lbz2
--- [ test.5 ] ---
--- [ test.5 output ] --- --- [ test.5 output ] --- Now you see that environment is damaged.
#763768#15
Date:
2014-10-04 05:37:19 UTC
From:
To:
I had discovered two moments which determine such behavior:
1) appending to variable in "$(eval ...)" takes only first value in chain.
    I.e.:
    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".

How do you think what I should change to fix bug and keep original logic?

#763768#20
Date:
2014-10-06 06:53:42 UTC
From:
To: