Q:

Foreach template in makefile recipe

Given the following Makefile fragment:
TOOLS=foo bar

define TOOL_install
install -c $(1) $$(prefix)/bin/$(1)
endef

.PHONY: install
install: all
        $(foreach tool,$(TOOLS),$(eval $(call TOOL_install,$(tool))))

Why does make install print "Nothing to be done for `install'." instead of executing the commands specified by the foreach?  (There is a tab before the foreach, and I have tried putting a tab inside the TOOL_install definition; it doesn't help.)
According to make -p the install target has no commands, which is obviously not as intended.
Elsewhere in the same makefile I've successfully used the same technique to create entire rules including command recipes; how can I make this work within an existing rule?
(If I replace eval with info then it prints the commands that I am expecting it to run.)
In this simple case I can get it to work by inlining the command:
install: all
        @$(foreach tool,$(TOOLS),install -c $(tool) $(prefix)/bin/$(tool) ; )

But I would like to know how to get the first form to work as expected, in case I need something more complicated in future.

A:

You should not use eval here, because you do not want to create dynamic constructs but constant rules. So just remove eval and add a ; at the end of your TOOL_install define:
TOOLS := foo bar

define TOOL_install
echo $(1);
endef

.PHONY: install
install:
    $(foreach tool,$(TOOLS),$(call TOOL_install,$(tool)))

After expansion your Makefile will look like:
.PHONY: install
install:
    echo foo; echo bar;

ANOTHER ANSWER:
We are using some temporary target install_foo and install_bar. These two targets are added to the install dependencies and declare just after. Moreover, in each temporary target we add dependency about the file to install (foo or bar). This way you can add as rules as you want, plus it's "parallel compliant".
prefix := foobar
TOOLS := foo bar

install: $(addprefix install_,$(TOOLS))

$(addprefix install_,$(TOOLS)): install_%: %
    install -c $< $(prefix)/bin/$<

.PHONY: install $(addprefix install_,$(TOOLS))

EDIT:
For the uninstal targets (without dependencies) you can use the patsubst function like this:
prefix := foobar
TOOLS := foo bar

uninstall: $(addprefix uninstall_,$(TOOLS))

$(addprefix uninstall_,$(TOOLS)):
    install -c $(patsubst uninstall_%,%,$@) $(prefix)/bin/$(patsubst uninstall_%,%,$@)

.PHONY: uninstall $(addprefix uninstall_,$(TOOLS))

A:

I've ended up going with a hybrid approach from my original question and jml's answer (thanks for the inspiration!).
TOOLS:=foo bar

.PHONY: all
all : $(TOOLS)

.PHONY: install $(addprefix install_,$(TOOLS))
install : $(addprefix install_,$(TOOLS))

.PHONY: uninstall $(addprefix uninstall_,$(TOOLS))
uninstall : $(addprefix uninstall_,$(TOOLS))

define TOOL_template
$(1): $$($(1)_OBJS)
        #commands to build it

install_$(1): $(1)
        install -c $(1) $$(prefix)/bin/$(1)

uninstall_$(1):
        rm $$(prefix)/bin/$(1)
endef

$(foreach tool,$(TOOLS),$(eval $(call TOOL_template,$(tool))))

Seems to do the trick.

