Я изменил рецепт %.d
, чтобы зависимости учитывались только в том случае, если файл все еще существует.Новое правило Makefile:
%.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
из main.c
, то инкрементная сборка будет выполнена успешно (поскольку она не будет пытаться перестроить main.o
), а полная сборка не удастся.
Есть ли другие недостатки этого подхода?Например, есть ли случаи, когда инкрементная сборка была бы неполной?