Evidently, assignments to pattern-specific simple variables don't build on top of each other, but in fact only the last one wins. So, for instance:
CFLAGS := -Wall
%.o: CFLAGS := $(CFLAGS) -march=haswell
%.o: CFLAGS := $(CFLAGS) -Werror
foo.o: foo.c
$(CC) $(CFLAGS) -c $< -o $@
drops the -march=haswell because the second assignment overwrites the first one and always uses the global versions (rather than the target-specific or pattern-specific versions) of variables it references in rvalues. But, confusingly, a target-specific variable does do the expected thing:
bar.o: CFLAGS := $(CFLAGS) -march=haswell
bar.o: CFLAGS := $(CFLAGS) -Werror
bar.o: bar.c
$(CC) $(CFLAGS) -c $< -o $@
This results in CFLAGS being -Wall -march=haswell -Werror.
Is there interest in changing the pattern-specific simple variable behavior to more closely match the target-specific variable behavior? The least invasive change I'd like to make is to have variable references in pattern-specific variable assignments first look for assignments in that pattern's environment before going to the global environment.
A more invasive behavior change would be to do roughly the same, but to look for assignments in increasingly general pattern environments all the way up to the global environment, but it's not even clear to me if this ordering is well-defined or if the code would lend itself to implementing such a thing.
An even more invasive change (and the one that I'd personally like, but which might break a lot of existing makefiles) would be to have all target- and pattern-specific simple variable assignments use the current rvalue from the most specific environment in which it can find an assignment. That would enable things like:
CFLAGS := -Werror
%.o: CFLAGS := $(filter-out -march=% -Wall,$(CFLAGS)) -march=haswell -Wall
foo.o: CFLAGS := $(filter-out -march=%,$(CFLAGS))
to result in "-Werror -Wall" for foo.o's CFLAGS.
Thoughts?
I haven't looked into the recursive variable behavior, but IMO it should do something roughly similar in terms of where it looks for assignments.
Kyle