GNU make: чистая цель зависит от включения
Я использую gmake и gcc -MM
для отслеживания зависимостей заголовков, следуя руководству. Механизм опирается на директиву makefile include
для импорта вычисленных зависимостей.
Поскольку файлы .d
включены в make файл, они должны существовать для любой цели, которая будет создана, включая clean
. Таким образом, перед тем, как clean
может делать правильные вещи, необходимо создать зависимости, а если не удается построить, то clean
просто больше беспорядок.
Помимо clean
, он хочет сделать все зависимости до построения любой цели.
Кроме того, если какой-либо файл будет изменен, чтобы включить несуществующий файл, тогда разрешение зависимости ломается и ничего не будет построено.
Если заголовок удаляется, тогда существующие файлы зависимостей содержат неподвижное имя в качестве цели, и ничего не будет создано до тех пор, пока не будут удалены файлы зависимых зависимостей... что невозможно сделать с помощью clean
.
Замена шаблона подстановки include
подстановочным знаком для включения всех существующих файлов зависимостей решает некоторые проблемы, но он по-прежнему не может очистить поврежденную зависимость, а устаревшие файлы зависимостей никогда не удаляются. Есть ли лучшее решение? Действительно ли ручной пример предназначен для реального использования?
Ответы
Ответ 1
Просто не предоставляйте правило для генерации файлов .d
. Хорошее объяснение того, почему это не так хорошо (в том числе и ваше дело), доступно в "Advanced Auto-Dependency Generation" Paul Smith - сопровождающий GNU Make.
В двух словах, следующий шаблон работает отлично для меня для всех случаев:
CPPFLAGS += -MMD -MP
%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -o [email protected] -c $<
-include $(OBJS:.o=.d)
См. также мои предыдущие связанные ответы:
Ответ 2
Решение состоит в использовании Условный синтаксис:
ifneq ($(MAKECMDGOALS), clean)
-include $(notdir $(SOURCES:.cpp=.d))
endif
Это делает чистую цель не вызывать цели *.d
, так как при запуске make clean
файлы *.d
не будут включены в Makefile.
Ссылка: https://www.gnu.org/software/make/manual/html_node/Goals.html
Ответ 3
Мой обычный шаблон выглядит как
all: target
target: .depends
## [snip build rules]
.depends:
gcc -MM $(CPPFLAGS) .... > [email protected]
-include .depends
Примечание -include
вместо include
. В принципе, он включает в себя условно: то есть файл iff
См. документацию: http://www.gnu.org/software/make/manual/make.html#Include