删除源文件后增量制作失败

时间:2019-05-17 21:46:16

标签: makefile gnu-make

我有一个带有两个源文件的简单C程序,Makefile自动生成依赖项,如section 4.14 of the GNU Make Manual中所述:

set allGroups = Application.Session.AddressLists.Item("All Groups")
set addressEntry = allGroups.AddressEntries.Item("<Enter Group Name Here>")
for each m in addressEntry.Members
  MsgBox m.Name
next

这将创建类似于all: main %.d: %.c @set -e; rm -f $@; \ $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ rm -f $@.$$$$ include main.d include hello.d main: main.o hello.o 的文件,如下所示:

main.d

如果我更改源代码(和Makefile)以删除hello.c和hello.h,就会出现问题。在下一次增量重建时,main.o main.d : main.c hello.h 失败:

make

make: *** No rule to make target `hello.h', needed by `main.d'. Stop. 文件已过期,但是main.d无法重建它,因为(根据陈旧的make),它仍然依赖于不再存在的{{1} }。

在这种情况下,干净的构建将成功。如何使增量构建也成功?

1 个答案:

答案 0 :(得分:0)

我修改了main.d配方,以便仅在文件仍然存在时才考虑依赖项。新的Makefile规则:

hello.h

第二个%.d%.d: %.c @set -e; rm -f $@; \ $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \ sed --in-place 's,\($*\)\.o[ :]*,\1.o $@ : ,g' $@.$$$$ ; \ sed 's^: \(.*\)^: $$(foreach t,\1,$$(if $$(wildcard $$t),$$t,))^g' < $@.$$$$ > $@; \ rm -f $@.$$$$ 修改为:

sed

因此,如果任何依赖文件消失了,main.d不会抱怨。

此方法的一个缺点是,在全新构建失败的情况下,增量构建可能会成功。例如,如果删除main.o main.d : $(foreach t,main.c hello.h,$(if $(wildcard $t),$t,)) 却没有从make中正确删除hello.h,则增量构建将成功(因为它不会尝试重建#include)完整版本会失败。

此方法是否还有其他缺点?例如,是否有增量构建不完整的情况?