Я предполагаю, что вы используете GNU Make и GCC. Сначала добавьте переменную для хранения списка файлов зависимостей. Предполагая, что у вас уже есть тот, который перечисляет все наши источники:
SRCS = \
main.c \
foo.c \
stuff/bar.c
DEPS = $(SRCS:.c=.d)
Затем включите сгенерированные зависимости в make-файл:
include $(DEPS)
Затем добавьте это правило шаблона:
# automatically generate dependency rules
%.d : %.c
$(CC) $(CCFLAGS) -MF"$@" -MG -MM -MP -MT"$@" -MT"$(<:.c=.o)" "$<"
# -MF write the generated dependency rule to a file
# -MG assume missing headers will be generated and don't stop with an error
# -MM generate dependency rule for prerequisite, skipping system headers
# -MP add phony target for each header to prevent errors when header is missing
# -MT add a target to the generated dependency
«$ @» - цель (вещь слева от:), «$ <» - предпосылка (вещь справа от:). Выражение «$ (<:. c = .o)» заменяет расширение .c на .o. </p>
Хитрость в том, чтобы сгенерировать правило с двумя целями, дважды добавив -MT; это делает как файл .o, так и файл .d зависимым от исходного файла и его заголовков; таким образом, файл зависимостей автоматически восстанавливается при изменении любого из соответствующих файлов .c или .h.
Опции -MG и -MP не дают сойти с ума, если отсутствует заголовочный файл.