The second expansion proposed by user657267 works well. GNU make also supports a kind of loop mechanism that you can use to instantiate several rules with very similar forms:
target1.PREREQUISITES = file11 file12 file13
target2.PREREQUISITES = file21 file22 file23
TARGETS = target1 target2
# $(1) is a parameter to substitute. The $$ will expand as $.
define MY_rule
$$(myDir)$(1).sfx : $$($(1).PREREQUISITES)
<same recipe here>
endef
$(foreach target,$(TARGETS),$(eval $(call MY_rule,$(target))))
foreach
loops over all words in $(TARGETS)
and assigns the current word to $(target)
.
call
performs an expansion of MY_rule
where it substitutes $(1)
with the current value of $(target)
and $$
with $
.
eval
instantiates the result of the call
expansion as a regular rule.
The result of the first iteration of foreach
, for instance, will be:
$(eval $(call MY_rule,target1))
The call
will evaluate as:
$(myDir)target1.sfx : $(target1.PREREQUISITES)
<same recipe here>
and eval
will instantiate it as a rule. Important: do not forget that call
performs a first expansion. So, if your <same recipe here>
contains $
symbols, do not forget to double them, unless their expansion by call
is fine. If your recipe makes use of shell variables, it is even possible that you end up with things like $$$$var
.
This mechanism is slightly more powerful and generic that the second expansion. It even works with more than one parameter to substitute and with nested loops:
target1.PREREQUISITES = file11 file12 file13
target2.PREREQUISITES = file21 file22 file23
TARGETS = target1 target2
DIRS = myDir
# $(1): target
# $(2): directory
define MY_rule
$(2)$(1).sfx : $$($(1).PREREQUISITES)
<same recipe here>
endef
$(foreach target,$(TARGETS),$(foreach dir,$(DIRS),$(eval $(call MY_rule,$(target),$(dir)))))
And you can even embed a foreach-eval-call
inside a define-endef
:
target1.PREREQUISITES = file11 file12 file13
target2.PREREQUISITES = file21 file22 file23
TARGETS = target1 target2
DIRS = myDir
# $(1): target
# $(2): directory
define MY_rule_1
$(2)$(1).sfx : $$($(1).PREREQUISITES)
<same recipe here>
endef
# $(1): directory
define MY_rule_2
$$(foreach target,$$(TARGETS),$$(eval $$(call MY_rule_1,$$(target),$(1))))
endef
$(foreach dir,$(DIRS),$(eval $(call MY_rule_2,$(dir))))