Общая проблема, с которой я сталкивался в Makefiles, заключается в том, что исполняемые файлы (и библиотеки в этом отношении) не обязательно пересвязываются при изменении списка зависимостей.Например:
SRCS=$(wildcard *.c)
CPPFLAGS=-MMD -MP
target: $(SRCS:.c=.o)
$(CC) $(LDFLAGS) $^ -o $@
-include $(SRCS:.c=.d)
Пока все хорошо: он автоматически обрабатывает любые изменения в исходных файлах и их включенных зависимостях.Если файл добавлен (из-за подстановочного знака, это означает просто добавление его в каталог, но явный список будет иметь ту же проблему), make видит его и связывает цель.Однако, когда исходный файл удален, make не знает, что цель должна быть перестроена.
Как мне заставить make (в частности, gmake) справиться с этой ситуацией?
По общему признанию, это не совсем обычная ситуация, так как удаление файла, скорее всего, будет означать, что другие файлы также должны быть изменены, что в любом случае приведет к повторной ссылке, но я уже видел это раньше.
Я имеюпридумать два решения, ни одно из которых не является идеальным.Во-первых, если мы сделаем список источников явным, а не подстановочным символом, мы можем сделать цель зависимой от файла Makefile.Изменение файла Makefile для удаления исходного файла приводит к повторной привязке цели.Это имеет две проблемы.Во-первых, вы должны удалить Makefile из $ ^ перед компоновкой, что немного уродливо (но выполнимо с помощью filter-out).Во-вторых, этот Makefile предназначен для использования в качестве шаблона, включенного в другие Make-файлы (которые указывают источники и цель) - вместо этого мы должны сделать цель зависимой от , что Makefile.Тьфу.
Второе решение состоит в том, чтобы включить некоторую логику, подобную следующей:
SRCS=$(wildcard *.c)
CPPFLAGS=-MMD -MP
target: $(SRCS:.c=.o)
$(CC) $(LDFLAGS) $^ -o $@
@echo '$$(if $$(filter-out $$(SRCS:.c=.o), $(SRCS:.c=.o)), .PHONY:target)' > target.d
-include $(SRCS:.c=.d)
-include target.d
Это создает файл target.d, который отслеживает список зависимостей и заставляет цель перестраиваться, есливсе удаленоЭто работает, но это некрасиво.Он также не может учитывать любые дополнительные не исходные зависимости, указанные включающим Makefile.
Есть ли официальный способ сделать это или, по крайней мере, лучший способ?
(КакКроме того, я бы также хотел очистить связанный объект и файлы зависимостей при удалении исходного файла, если это возможно. Это могло бы быть возможно, расширив мое второе решение и сделав его еще более уродливым.)