gpt4 book ai didi

makefile - Makefile 中的复杂模式规则

转载 作者:行者123 更新时间:2023-12-01 00:57:15 26 4
gpt4 key购买 nike

我有以下 makefile 用于从某些模板生成文件,生成的文件有两种可能的扩展名:

%.tex: %.tex*_tpl
./generate $@_tpl -o $@

%.xml: %.xml*_tpl
./generate $@_tpl -o $@

依赖列表将在此处匹配 a.tex_tpl 之类的内容。 , a.tex-subpart1_tpl , a.tex-subpart2_tpl .

虽然这有效,但有没有办法避免重复?例如通过匹配 *.{tex,xml}在规则名称中并在依赖项列表中使用整个匹配的名称?看起来像这样的东西:
%.{tex,xml}: $@_tpl
./generate $< -o $@

(虽然我知道 %.{tex,xml} 不是有效的规则名称,您不能在依赖项列表中使用 $@)

或任何其他(更清洁?)方式。

最佳答案

在我看来,这符合您的要求:

#
# I've assumed that files of the form:
#
# a.xml_tpl
# b.tex_tpl
#
# determine what targets you want to build
#
TARGETS:=$(patsubst %_tpl,%,$(wildcard *.xml_tpl *.tex_tpl))

.PHONY: all
all: $(TARGETS)

.SECONDEXPANSION:
$(TARGETS): %: $$(wildcard %*_tpl)
./generate $^ -o $@

关键是用 .SECONDEXPANSION 允许 $$(wildcard %*_tpl)将在第二个扩展阶段进行评估。双 $顺便说一下,这不是打字错误;它保护表达式在第一次扩展时不被评估。

如果我用这些文件填充目录:
a.tex-subpart1_tpl
a.tex_tpl
a.xml-subpart1_tpl
a.xml-subpart2_tpl
a.xml_tpl

并运行 make -n ,我在控制台上得到了这个:
./generate a.xml_tpl a.xml-subpart1_tpl a.xml-subpart2_tpl -o a.xml
./generate a.tex_tpl a.tex-subpart1_tpl -o a.tex

为什么要二次扩容?

如果没有第二次扩展,您必须拥有 $(wildcard %*_tpl)在依赖中,因为与 $$通配符函数永远不会执行。相反,make 会处理 $$(wildcard..)从字面上看作为依赖,这显然是错误的。

好的,所以 $(wildcard %*_tpl)将在 make 第一次穿过那条线时进行评估(这是“第一次扩展”)。当时 %尚无值(value),所以 wildcard大致会做类似 ls %*_tpl 的事情在命令行。

出于速度的原因,默认情况下 make 不会让您有机会在第一次扩展之后进行任何评估。如果您想要以后的机会,您必须指定 .SECONDEXPANSION ,开启第二次扩展处理。 Make 仍然像往常一样执行第一次扩展。这就是为什么您需要拥有 $$(wildcard : 转化为 $(wildcard在第一次扩张期间。第二次扩容时make看到 $(wildcard %*_tpl) , 替换 %使用实际词干,然后执行 wildcard函数使用实际词干而不是文字 % .

为什么 $(TARGETS)在模式规则中?

模式规则可以写成:
%: $$(wildcard %*_tpl)
./generate $^ -o $@

没有 $(TARGETS) .然而,这条规则什么也不做,因为它是 "match-anything rule" .基本上,如果make从表面上看这样的规则,那么计算成本会很大,而且很可能不是 Makefile的作者的情况。真正意味着将此规则应用于任何文件。所以这样的规则是有限制的,在这里的 Makefile 中使其无用。

添加 $(TARGETS)使其成为 static pattern rule ,这不是匹配任何规则。新增 $(TARGETS)前面的目标模式告诉 make 规则仅适用于这些目标,而不适用于其他目标。

关于makefile - Makefile 中的复杂模式规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26672148/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com