虽然我对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.a
,file_1.a
,file_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
文件生成图像...)
答案 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
文件(因为它已过期)。