I am using GNU make 3.81. Here is a test makefile that demonstrates the problem:
define BOZO
a$(1): b c
touch a$(1)
endef
$(foreach i,1 2 3,$(call BOZO,$(i)))
The idea here is to use a macro template (BOZO) to generate rules that follow a predictable pattern.
Problem: when I run make on this makefile I get an error saying:
Makefile.fake:10: *** multiple target patterns. Stop.
(where line 10 is the line with the foreach).
Now, I know what that error normally indicates. Let’s see what that line expands to by using the info function to send the expansion to standard out. I change line 10 to be:
$(info $(foreach i,1 2 3,$(call BOZO,$(i))))
and I run:
$ make -n
a1: b c
touch a1
a2: b c
touch a2
a3: b c
touch a3
make: *** No targets. Stop.
Note that the “no targets” message is expected, since the $(info …) function evaluates to empty but causes make to print the generated rules.
Let’s run those rules then shall we?
$make -n > out.txt
make: *** No targets. Stop.
$make -f out.txt a1 a2 a3
touch a1
touch a2
touch a3
$
AAARGH! The rules work fine. So… is the bug in make, or in my understanding?
One final clue that might help diagnose: if I change the foreach line to:
$(foreach i,1,$(call BOZO,$(i)))
(so that foreach has only one iteration)
and then do
$make a1
I get a different error:
make: *** No rule to make target `a1'. Stop.
I don’t know of any way to “see” the expansion of $(foreach ) that make sees except for $(info ), and its output is legal, so I’m quite stumped.
The eval function tells Make to parse the structures as makefile syntax, to “enact” them. I’m not sure why Make objected to the un-eval’d rules this particular way, but that’s kind of academic.