makefile:先决条件中的%pattern $(变量)

时间:2017-07-18 02:51:46

标签: variables design-patterns makefile prerequisites

我有类似的东西有效:

target1.PREREQUISITES = file11 file12 file13
target2.PREREQUISITES = file21 file22 file23

$(myDir)target1.sfx : $(target1.PREREQUISITES)
    <same recipe here>

$(myDir)target2.sfx : $(target2.PREREQUISITES)
    <same recipe here>

这就是我想做的事情,但它不起作用:

target1.PREREQUISITES = file11 file12 file13
target2.PREREQUISITES = file21 file22 file23

$(myDir)%.sfx : $(%.PREREQUISITES)
    <commun recipe here>

它始终表示没有任何事情要做,因为目标是最新的。

我觉得问题可能是每个制作阶段所做的事情,我的意思是,先做%或$。它应该工作得很好吗?

3 个答案:

答案 0 :(得分:3)

user657267提出的第二次扩展运作良好。 GNU make还支持一种循环机制,您可以使用它来实例化具有非常相似形式的多个规则:

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),将$$替换为$
  • evalcall扩展的结果实例化为常规规则。

例如,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))))

答案 1 :(得分:1)

你需要secondary expansion之类的东西来实现这一点,否则先前条件中变量的扩展会在替换模式之前发生,并且你没有&#39; t定义了一个名为site_id的变量。

(32 with 5, and 32with 6)

答案 2 :(得分:-1)

感谢用户657267的回答,它确实有效,它给了我很好的领导。对于那些不太熟悉的人,请注意双美元符号。但是,我在这里包括我的答案,因为它仍然使用%符号,这是我原始问题的一部分,并且与您的工作一样好。我使用以下解决方案。

.SECONDEXPANSION:

$(mydir)%.sfx: $$(%.PREREQUISITES)
    echo $^

我刚注意到并注意到,当使用辅助扩展时,make并没有告诉您缺少先决条件没有规则,而是显示一条误导性消息,表示没有制定目标的规则。