操作顺序:在构建新文件之前擦除旧文件

时间:2016-06-07 21:06:16

标签: makefile gnu-make

虽然我对makefile很好,但是我有一个问题,我只能解决makefile中命令的顺序问题。 让我们详细说明。

假设我有一些程序可以生成一些" a"类型的文件。我想手动接受这些并通过一些工具来处理它们,这些工具将输入作为输入#34; a"文件并生成" b"。

类型的文件

所以我的makefile包含以下模式规则:

%.b:%.a
   $(MYTOOL) $< >$@

我收集所有要在变量B_FILES中构建的文件,从&#34; a&#34;的列表中构建。文件:

A_FILES = $(wildcard *.a)
B_FILES = $(patsubst %.a,%.b,$(A_FILES))

这是通过一般呼叫目标调用的:

build_b_files: $(B_FILES)
   @echo "done!"

完美无缺。

现在的问题是:主程序的每次运行都可以生成不同数量的&#34; A&#34;文件,具有一些常见的命名方案(例如file_0.afile_1.afile_2.a,...)。 但是如果一个运行产生了20个文件,而下面只有10个文件,那么我仍然有剩下的10个文件来自后一个运行。

所以我想做的是让我的build_b_files目标自动删除所有旧的&#34; b&#34;在构建新文件之前文件。

我尝试使用order-only prerequisite,但以下操作失败:它只是每次重建所有文件,然后删除它们(!)。

erase_all_B:
    @rm *.b

build_b_files: $(B_FILES) | erase_all_B
    @echo "- Done target $@"

我可能误解了这个&#34;仅限订单&#34;的概念。

我如何实现这一目标?

修改:澄清问题,请参阅以下(模拟)会话,了解我要查找的内容(ls仅在此处显示相关文件):

$ myapp some-arguments... (will produce 4 'a' files)
$ ls -l            (stripped)
june 8 16:00 file_0.a
june 8 16:00 file_1.a
june 8 16:00 file_2.a
june 8 16:00 file_3.a
$ make build_b_files
$ ls -l
june 8 16:00 file_0.a
june 8 16:00 file_1.a
june 8 16:00 file_2.a
june 8 16:00 file_3.a
june 8 16:00 file_0.b
june 8 16:00 file_1.b
june 8 16:00 file_2.b
june 8 16:00 file_3.b
     .... (some time) ....
$ myapp some-other-arguments... (will produce only 3 'a' files)
$ ls -l
june 8 17:00 file_0.a
june 8 17:00 file_1.a
june 8 17:00 file_2.a
june 8 16:00 file_3.a
june 8 16:00 file_0.b
june 8 16:00 file_1.b
june 8 16:00 file_2.b
june 8 16:00 file_3.b
$ make build_b_files
$ ls -l
june 8 17:00 file_0.a
june 8 17:00 file_1.a
june 8 17:00 file_2.a
june 8 17:00 file_0.b
june 8 17:00 file_1.b
june 8 17:00 file_2.b

(对于那些想知道,这是关于graphviz,从dot文件生成图像...)

2 个答案:

答案 0 :(得分:2)

您需要在重新生成任何b文件之前清除所有b文件,因此您所说的erase_all_B应该是$(BFILES)本身的先决条件,而不是build_b_files:< / p>

.PHONY: erase_all_B
erase_all_B: ; $(RM) *.b
$(B_FILES): erase_all_B

使用以下

进行测试
all: bar baz
bar baz: foo
ba%:
    @echo bar baz
foo:
    @echo foo

答案 1 :(得分:1)

如果生成.a文件的工具删除旧文件,您可以使用以下内容轻松构建“.b文件列表以便删除”

TO_REMOVE := $(filter-out $(B_FILES),$(wildcard *.b))

如果生成.a文件的工具没有删除旧文件,为什么要删除匹配的.b文件?它们将被重新生成,因为.a文件仍在此处。如果.a文件被修改,则make将重新生成相应的.b文件(因为它已过期)。