所以我有一个带有目标依赖的makefile,如下所示:
all: $(foreach lang, $(LANGS), $(foreach models,$(MODELS),targetName$(model).xml$(lang)))
,targetName目标如下所示:
targetName%.xml%: MODEL\=% targetName.xml*
但它不起作用。我收到这个错误:
make[1]: *** No rule to make target `targetNameMYMODEL.xmlen', needed by `all'. Stop.
然而,在targetName目标中使用硬编码语言调用'all'就像这样:
all: $(foreach lang, $(LANGS), $(foreach models,$(MODELS),targetName$(model).xmlen))
并且在all或targetName中没有语言的情况下调用'all'也可以正常工作。我想也许Makefile不喜欢在目标名称中有两个百分号。
另外,由于我继承了这个makefile,有人可以告诉我MODEL \ =%意味着什么吗?还有另一个目标看起来像这样:MODEL%: ;
但我不确定\ =%意味着什么。
编辑: 所以基于这个回应进一步澄清:
我有一个列表,例如5个模型和5个语言列表,目标是生成25个文件,每个语言和模型组合一个。
targetName%.xml目标最初将构建一个名为targetName.xml的文件,但现在我需要它来构建类似targetName.xml的东西这就是我需要两个%符号的原因。
我正在使用嵌套的foreach循环遍历这两个列表,如上所示,但是我很难将这些变量传递给目标。我已经尝试从foreach语句中导出语言变量,我已经尝试将targetName%。xml的内容放在for循环中以循环遍历那里的语言。后者不起作用,因为在循环的'do'部分有Makefile命令(例如eval)。
答案 0 :(得分:3)
你没错,Make不喜欢目标名称中的两个%
符号。这只是Make的通配符处理方式中的一种,并不是所有人都希望的。有一种方法可以生成所有模式规则,迭代一个变量的值(并且另一个变量使用%
);它有点难看,但如果这就是你想要的,我们可以告诉你。
但这条线路很乱:
targetName%.xml%: MODEL\=% targetName.xml*
除了目标中有两个通配符的问题之外,最后一个preq targetName.xml*
将意味着:一个名为targetName.xml*
的目标(或文件)。星号不会展开,也不会展开以targetName.xml
或其他任何内容开头的所有现有文件的列表。
然后有MODEL\=%
,表示此makefile的作者有点困惑(并且不相信测试)。如果通配符的值为foo
,则表示先决条件是名为MODEL=foo
的目标(或文件)。 \
“转义”=
,因此Make不会中止,但这只是抑制健康的错误消息。我认为作者的想法是这样的:
targetName%.xml: MODEL=%
targetName%.xml: $(wildcard targetName.xml*)
do some things
第一条规则不是指定先决条件,它是设置特定于目标的变量。因此,当Make尝试按targetNamefoo.xml
构建doing some things
时,变量MODEL
将在该命令的上下文中具有值foo
。第二条规则有一个preq列表,由wildcard
生成;你不能在一行中混合特定于目标的变量和preqs。
我们可以提供进一步的建议,但如果我们能够更清楚地看到您正在尝试做什么,这将有所帮助。
答案 1 :(得分:2)
值得注意的是official documentation:
10.5定义和重新定义模式规则
您可以通过编写模式规则来定义隐式规则。模式规则看起来像一条普通规则,只是它的目标包含字符
%
(恰好是其中的一个)。目标被认为是匹配文件名的模式。%
可以匹配任何非空子字符串,而其他字符只能匹配它们自己。前提条件同样使用%
来显示其名称与目标名称的关系。因此,模式规则
%.o : %.c
介绍了如何从另一个文件 stem.c 中创建任何文件 stem.o 。请注意,在模式变量中使用
%
进行扩展会在所有变量或函数扩展后发生,该扩展在读取makefile时发生。参见How to Use Variables和Functions for Transforming Text。
来源:https://www.gnu.org/software/make/manual/html_node/Pattern-Rules.html