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)

См. также мои предыдущие связанные ответы:

Ответ 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