make clean:只删除已经生成的文件

make clean: Only remove files that have been generated

我正在使用 Makefile 将 pdf 文件转换为 txt 文件。

我已经实施了一个 clean 目标,该目标将删除所有 .txt 文件。但是,我不想删除源文件,只希望删除那些 生成的 .

示例: 我的文件夹中有以下文件:

pdfsource.pdfdonotharm.txt

运行 我的 makefile 将创建以下文件:

pdfsource.txt

现在,我的 clean 看起来像这样:

rm -f *.txt

使用 make clean 不仅会删除所需的 pdfsource.txt,还会删除 donotharm.txt

我想我可以使用:.PRECIOUS: donotharm.txt,但这确实很具体。我想要一个通用解决方案。

提前致谢!

您可以在 make 变量中列出生成的文件,并仅使用它来清理这些文件:

PDF  := $(wildcard *.pdf)
TEXT := $(patsubst %.pdf,%.txt,$(PDF))
...
clean:
    rm -f $(TEXT)

或者,如果您更喜欢更紧凑(但可读性稍差)的形式:

clean:
    rm -f $(patsubst %.pdf,%.txt,$(wildcard *.pdf))

当然,只有当没有 {foo.pdf,foo.txt} 对要保留 foo.txt 不被 make clean 删除时,这才有效。

注意:在这种情况下,使用 make 变量通常是个好主意,因为它们可以在各种规则之间共享。示例:

PDF  := $(wildcard *.pdf)
TEXT := $(patsubst %.pdf,%.txt,$(PDF))

.PHONY: all clean

all: $(TEXT)

$(TEXT): %.txt: %.pdf
    pdftotext $< $@

clean:
    rm -f $(TEXT)

另一种方法:"make -nps" 为您提供有关依赖项的所有 make 元数据。对于任何中间文件,它都会打印

filename: ...

因此您可以使用通用 "clean" 规则准确删除此类文件:

clean:; MAKEFLAGS= ${MAKE} -j1 -spinf $(word 1,${MAKEFILE_LIST}) \
| sed -n '/^# I/,$${/^[^\#\[%.][^ %]*: /s/:.*//p;}; 1s|.*|${clean}|p' | xargs rm -rf

第一行处理默认生成文件以外的生成文件的使用(生成文件、GNUmakefile、生成文件) 在 "sed" 命令中:

/^# I/,$ 

...选择具有依赖关系的make metadata的区域。

/^[^\#\[%.][^ %]*: /

... 过滤掉注释、隐式规则和没有依赖项的文件(尾随 space)。它不会过滤掉虚假目标;那好吧。 最后:

1s|.*|${clean}|p

为 "clean" 添加任何明确的目标——你知道 make 没有;例如

clean +=  tmpdir/*  *.gcda