主目标完成后,将删除由依赖项创建的文件

时间:2016-05-31 12:02:05

标签: gnu-make

我对gnu make的行为有疑问。具体来说,如果依赖关系目标生成一个尚不存在的文件,则在“主”目标完成时将删除该文件。

我确信有很好的理由说明为什么会这样,但我该如何解决呢?

我已经详细说明了下面的情况,并添加了一个示例Makefile,显示了我想要做的事情的概念。

感谢您的意见。

情况:

下面的示例文件(实际Makefile的“虚拟示例”)的目的是从Markdown文件生成“html”和“pdf”。

默认目标是pdf,它将递归调用目标%.pdf,而目标%.html依次为%.md,因此%.pdf。到目前为止一切顺利,如果目录中只包含markdown文件,我将在生成“pdf”之前生成“html”文件。

如果您运行该示例,您会注意到在usr@cmptr $ make Generated: sof_example.md Generated: sof_example.html Generated: sof_example.pdf rm sof_example.html sof_example.md usr@cmptr $ 目标完成后删除了“html”文件。终端输出为:

make

但是,如果文件在执行usr@cmptr $ make clean usr@cmptr $ touch sof_example.html sof_example.md usr@cmptr $ make Generated: sof_example.pdf usr@cmptr $ 之前存在,则输出为:

html

有没有办法可以优雅地解决这个问题,即不添加更多递归调用,或者特定于%.pdf作为依赖项的示例,因为make每次都会执行# --------------------------------------------------------------------------- # # summary: Make file generating 'html' and 'pdf' from a markdown ('md') file # usage: make # note: Recursive # --------------------------------------------------------------------------- # TARGETS := sof_example SHELL=/bin/bash .PHONY: all clean all: pdf # Dummy target, the markdown file will normally located in TARGETS %.md: @touch $(@) @printf "Generated: %s\n" $(@) # HTML target: Generates HTML file from markdown %.html: %.md @touch $(@) @printf "Generated: %s\n" $(@) # PDF target: Generates pdf version of the HTML, e.g. using `wkhtmltopdf` %.pdf: %.html @touch $(@) @printf "Generated: %s\n" $(@) pdf html: @$(MAKE) --no-print-directory $(addsuffix .$(@), $(TARGETS)) # Will remove ALL files with name TARGETS, regardless of suffix clean: @$(RM) $(TARGETS).* # EoF Option::margin() 1}}被执行。

示例文件:

Margin

1 个答案:

答案 0 :(得分:1)

您所看到的是因为您隐含的模式规则的链接:

%.md -> %.html -> %.pdf

引导make推断出%.md%.html仅仅是中间的 对于任何给定的%.pdf,制作%的副产品。在那种情况下它 默认假设是您不想保留中间体。

如果你想要保留中间人,你可以告诉make通过声明 makefile中任意位置的特殊目标.SECONDARY:

.SECONDARY:
没有先决条件的

将保留所有中间体。有先决条件, e.g。

.SECONDARY: $(addsuffix .html,$(TARGETS))

只保留那些先决条件的中间体。

请参阅4.9 Special Built-in Target Names