%.d: %.c
Все файлы, заканчивающиеся в .d
можно сделать, используя это правило, до тех пор, как существует .c
файл с той же директории и стеблевой относительно текущего каталога или одной из vpaths.
mkdir -p $(@D)
Создать верхний и все промежуточные каталоги для $(@D)
, что автоматическая переменная марка, которая расширяется в каталог части текущей цели.
$(CC) $(CFLAGS) $(CPPFLAGS) -M $< | \
Призовите C компилятор на первом предпосылки (whatever.c
) и сказать ему, чтобы вывести список зависимостей замыкающих на стандартный вывод. Труба этот выход к
sed 's,\($(notdir $*)\.o\) *:,$(dir [email protected])\1 [email protected]: ,' > [email protected]
СЭД. Правила на выходе будут иметь тот же путь, что и исходные файлы, но тот, кто написал это правило, хочет, чтобы файлы объектов были в другом каталоге, поэтому нам нужно, чтобы sed заменил пути.
Sed фиксирует любые правила с целями, заканчивающимися .o
, которые соответствуют $(notdir $*)
. $*
- это еще одна автоматическая переменная, которая расширяется до шаблона, который соответствует %
в текущем правиле, и notdir
лишит любые части каталогов, чтобы вы оставались со стеком имени файла без расширения.
Sed затем присоединяет $(dir [email protected])
к цели объектного файла, который то же самое, как $(@D)
мы видели выше, и добавляет файл зависимостей сам ([email protected]
) в качестве мишени тех же предпосылок. Этот вывод перенаправляется в файл с именем текущей цели + .tmp
.
mv [email protected] [email protected]
Перемещает предыдущий файл в реальную цель правила.
Side Примечание: если вы не возражаете файлы зависимостей генерируемые в том же каталоге, что и объектные файлы затем эти рецепты являются устаревшими, вы можете достичь того же с чем-то вроде:
sources := src/somefile1.c src/somefile2.c
objects := $(sources:src/%.c=obj/%.o)
deps := $(objects:.o=.d)
CFLAGS := -MMD -MP
.PHONY: all
all $(objects)
$(objects): obj/%.o: src/%.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
-include $(deps)
Отлично. Спасибо вам! – Gaston