用戶657267提出的第二種擴展工作良好。 GNU使還支持一種,你可以用它來實例化幾個規則非常相似的形式循環機制:
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
環比在$(TARGETS)
所有文字和當前的單詞分配給$(target)
。
call
執行的MY_rule
的膨脹,其中它可以代替$(1)
與$(target)
和$$
與$
的當前值。
eval
實例化call
擴展的結果作爲常規規則。
的foreach
第一次迭代中,對實例的結果,將是:
$(eval $(call MY_rule,target1))
的call
將作爲評估:
$(myDir)target1.sfx : $(target1.PREREQUISITES)
<same recipe here>
和eval
將實例它作爲一項規則。 重要:不要忘記,call
執行第一次擴展。因此,如果您的<same recipe here>
包含$
符號,請不要忘記將它們加倍,除非它們的擴展是call
是好的。如果你的配方使用shell變量,甚至有可能你最終得到的結果是$$$$var
。
這個機制稍微強大一些,通用的第二個擴展。它甚至有一個以上的參數可與嵌套循環替換和:
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)))))
你甚至可以嵌入foreach-eval-call
內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))))
謝謝。它可以工作,但是我得到了第二個不希望的效果:如果其中一個必備文件丟失,例如file12,請抱怨沒有制定目標的規則,而不是抱怨缺少制定file12的規則。 –
不幸的是,make手冊沒有在帶''''符號的先決條件中使用的變量示例。在前提條件中,我確實只看到一個帶有'%'的例子,但它不是一個變量,而是一個函數,但是我不清楚爲什麼這個例子可以工作,而不是我的。這是手冊中的內容:'%.o:$$(addsuffix /%.c,foo bar)foo.h' –
其實我只是用這種方法試了一個測試文件,並且和你的建議一樣好,理解爲什麼:**'$(myDir)%。sfx:$$(%。PREREQUISITES)'**並且它與您的副作用相同:它不會告訴您缺少必備文件。 –