我可以在makefile目标中有多个%的符号吗?

时间:2012-06-14 15:01:26

标签: makefile gnu-make

所以我有一个带有目标依赖的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)。

2 个答案:

答案 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 VariablesFunctions for Transforming Text

来源:https://www.gnu.org/software/make/manual/html_node/Pattern-Rules.html