I'm not saying this should be considered a bug but it's at least an "interesting result". I've always followed the rule of thumb that simple (:=) assignment should be used when the RHS contains $(shell ....), and this is still a good mnemonic 99.9% of the time, but I've run across a case where it actually loses. Consider the following makefile:
$ cat Makefile TARGETS := aa bb cc dd .PHONY: all all: $(TARGETS) $(TARGETS): at := $(shell set -x; date) $(TARGETS): @:$(info Making $@ at $(at)) when making only a subset of declared targets. With simple := assignment a shell is invoked for every target including those not being built: $ make bb + date + date + date + date Making bb at Fri Jun 5 08:12:25 PDT 2020 but with recursive = assignment only the required one is used: $ make bb + date Making bb at Fri Jun 5 08:12:36 PDT 2020 I understand why this happens but it does raise the question of how simple assignment should work in this case. Here's what the manual says: "The value of a simply expanded variable is scanned once and for all, expanding any references to other variables and functions, *when the variable is defined*." But in a target-specific context should the variable be considered "defined" at the time it's parsed or at the time it's needed?