2016-07-14 9 views
1

Я использую Makefile, включая правило для создания файла зависимостей. Компилятор - это GCC.Создайте файлы зависимостей в Makefile

%.d: %.c 
    mkdir -p $(@D) 
    $(CC) $(CFLAGS) $(CPPFLAGS) -M $< | \ 
    sed 's,\($(notdir $*)\.o\) *:,$(dir [email protected])\1 [email protected]: ,' > [email protected] 
    mv [email protected] [email protected] 

Я совершенно новый в технике Makefile, и я нахожу это немного трудно понять это правило, состоящее из смеси нескольких вариантов.
Может ли кто-нибудь дать простое объяснение, как это правило работает? Спасибо заранее.

ответ

2

%.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) 
+0

Отлично. Спасибо вам! – Gaston