makefile - 使 .SECONDEXPANSION 配方执行两次
问题描述
使用 GNU make,我试图解决一个类似于make recipe 执行两次的问题——也就是说,让 Makefile 配方运行两次。然而,在我的例子中,配方是在.SECONDEXPANSION
目标下运行的,两个不同的运行将使用不同的参数调用,以从同一个输入文件生成不同版本的输出文件。也就是说,使用输入文件foo
,这个示例 Makefile 应该可以通过调用make foo.pdf
或make foo.expanded.pdf
构建一个 .pdf 文件,或make all
构建两个 .pdf 文件:
.PHONY: all
all: foo.pdf foo.expanded.pdf
.SECONDEXPANSION:
%.expanded.pdf %.pdf: %
@echo building $(basename $@)
在该答案中给出的两个解决方案中,第一个是不合适的,因为它总是运行规则两次;我希望它在用户要求时运行两次。
在那里发布的第二个解决方案概念上是我正在寻找并在上面的示例 Makefile 中实现的,只有一个小问题是它不起作用:虽然all
目标将两个 .pdf 文件都列为依赖项,但只有一个是在什么时候构建make all
的跑。
有没有办法告诉 GNU make 在 a 下使用相同的规则构建两个不同的文件.SECONDEXPANSION
?
编辑:在问题描述中澄清了相同的输入文件用于构建输出文件的两个版本,并修改了示例 Makefile 以包含此依赖项。
编辑:我想要一个尽可能可扩展的解决方案;也就是说,如果输入文件名包含点,它应该可以工作,指定额外的输出文件foo.reduced.pdf
应该只需要根据需要调整目标和配方等。这限制了执行依赖于在这个狭窄示例中给出的文件名的字符串手术(例如,%.pdf: $$(firstword $$(subst ., ,$$*))
如果输入文件可以是foo
或foo.bar
) ,则将规则更改为失败。
解决方案
你的问题与.SECONDEXPANSION
. 您可以放弃它,问题将是相同的。
您的问题是您正在使用具有多个目标模式的模式规则,并期望它与具有多个目标的显式规则类似。但事实并非如此(事实上,您不能同时拥有包含模式和显式目标的规则)。
对于具有多个目标模式的模式规则,Make 将相同的模式匹配到所有的%
,包括目标中的多次,然后假设它只需使用该模式执行一次配方,它将生成所有匹配的目标。
在您的情况下,最好的方法是使用多个规则(我更改了您的食谱,因为echo
用作 Make 食谱是一个坏主意):
.PHONY: all
all: foo.expanded.pdf foo.pdf
RECIPE = touch $@
%.expanded.pdf:
$(RECIPE)
%.pdf:
$(RECIPE)
推荐阅读
- python - Python中类的单元测试实例化
- sql - 具有分组聚合的 SQL 计数
- node.js - 使用从请求返回的“正文”
- javascript - Json 数据未显示在网页的 div 中
- javascript - 修改 URL 允许一些用户看到他们不应该看到的内容
- svelte - 迭代异步函数导致苗条
- reactjs - 在组件中同时获取通过 props 和 redux 状态的反应
- r - 如何使用来自两个 XTS 的数据来创建一个新的 XTS?
- react-native - 如何模拟 React Functionnal Component 方法?
- r - R pdftools 转换为图像时没有得到所有层的pdf