生成文件:在前提条件$(变量)%图案

问题描述:

我有这样的事的作品:

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> 

它总是说因为目标是最新的,所以没有什么可做的。

我有这样的感觉,问题可能是每个制作阶段都做了什么,我的意思是,先做的是%或$。它应该工作得很好吗?

感谢user657267的回答,它的工作和它给了我一个很好的领导。对于那些不太熟悉的人,请注意双美元符号。不过,我在这里列出了我的答案,因为它仍然使用%标志,这是我原始问题的一部分,与您的标准一样好。我正在使用以下解决方案。

.SECONDEXPANSION: 

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

我只是注意到了,意识到这一点,在使用二次扩张时做出不告诉你,一缺少的必备条件没有规则,而是显示一个误导性的消息说,没有规则使目标

你需要像secondary expansion这个工作,否则该变量的前提条件中发生之前图案取代扩大,而你还没有定义了一个名为%.PREREQUISITES变量。

.SECONDEXPANSION: 

$(mydir)%.sfx: $$($$*.PREREQUISITES) 
    echo $^ 
+0

谢谢。它可以工作,但是我得到了第二个不希望的效果:如果其中一个必备文件丢失,例如file12,请抱怨没有制定目标的规则,而不是抱怨缺少制定file12的规则。 –

+0

不幸的是,make手册没有在带''''符号的先决条件中使用的变量示例。在前提条件中,我确实只看到一个带有'%'的例子,但它不是一个变量,而是一个函数,但是我不清楚为什么这个例子可以工作,而不是我的。这是手册中的内容:'%.o:$$(addsuffix /%.c,foo bar)foo.h' –

+0

其实我只是用这种方法试了一个测试文件,并且和你的建议一样好,理解为什么:**'$(myDir)%。sfx:$$(%。PREREQUISITES)'**并且它与您的副作用相同:它不会告诉您缺少必备文件。 –

用户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-calldefine-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))))