生成文件:在前提条件$(变量)%图案
问题描述:
我有这样的事的作品:
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 $^
答
用户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)'**并且它与您的副作用相同:它不会告诉您缺少必备文件。 –