2013-04-07 3 views
1

Я следовал this tutorial. В нем объясняется создание Makefile, который заботится о зависимостях. Я сделал следующее Makefile, который работает в соответствии со следующей структурой:Понимание Makefile с автоматическими зависимостями: проблемы с 'sed' частью

folder--|Makefile 
    |src----|(all .c and .h files here) 
    |obj----|(all objects file are made here) 
    |bin----|(target is made here) 

Makefile, является:

TARGET = exec 

CC  = gcc 
CFLAGS = -g -I. 
LINKER = gcc -o 
LFLAGS = -I. -lm -lpthread 

BINDIR = bin 
OBJDIR = obj 
SRCDIR = src 
INTERFACE = interface 
STD = -std=c99 

PROGRAMSOURCES := $(wildcard $(SRCDIR)/*.c) 
PROGRAMINTERFACE:= $(wildcard $(INTERFACE)/*.h) 
OBJECTS  := $(PROGRAMSOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o) 

$(BINDIR)/$(TARGET) : $(OBJECTS) 
    $(LINKER) [email protected] $(LFLAGS) $(OBJECTS) $(STD) 

#pull the dependencies to the .o files 
-include $(OBJECTS:.o=.d) 

#the -o [email protected] says to put the output of the compilation in the file named on the left side of the :. 
#the $< is the first item in the dependencies list. Basically the name of the .c file which is to be compiled. 
$(OBJECTS)  : $(OBJDIR)/%.o :$(SRCDIR)/%.c 
    $(CC) $(CFLAGS) -c $< -o [email protected] $(STD) 
    $(CC) $(CFLAGS) -MM $< > $*.d 
    @mv -f $*.d $*.d.tmp    #changes file name 
    @sed -e 's|.*:|$*.o:|' < $*.d.tmp > $*.d #Unable to understand 
    @sed -e 's/.*://' -e 's/\\$$//' < $*.d.tmp | fmt -1 | \ 
    sed -e 's/^ *//' -e 's/$$/:/' >> $*.d  #Unable to understand 
    @rm -f $*.d.tmp 

.PHONY : run 
run  : 
    ./$(BINDIR)/$(TARGET) ${TYPE} ${INP_FILE} 

print: 
    @echo $(OBJECTS) 

я понял, что он пытается предобработать временный секретарь файл для создания авто зависимость. То, что я не могу понять, это то, как это делается. Вот две строки, которые я хочу объяснить:

@sed -e 's|.*:|$*.o:|' < $*.d.tmp > $*.d #Unable to understand 
@sed -e 's/.*://' -e 's/\\$$//' < $*.d.tmp | fmt -1 | \ 
sed -e 's/^ *//' -e 's/$$/:/' >> $*.d  #Unable to understand 

Я никогда не использовал sed раньше, поэтому у меня возникли проблемы.

Любая помощь приветствуется.

ответ

3

Предположим, вы строите obj/foo.o из src/foo.c, поэтому файл foo.d.tmp содержит:

foo.o: src/foo.c src/foo.h src/bar.h 

Теперь первый sed заявление:

@sed -e 's|.*:|$*.o:|' < $*.d.tmp > $*.d 

«Читать foo.d.tmp, принять все до двоеточия и изменения его в 'foo.o', и напишите результат на foo.d. " Так что теперь foo.d содержит:

foo.o: src/foo.c src/foo.h src/bar.h 

(Никаких изменений в этом случае.) Теперь следующая команда:

@sed -e 's/.*://' -e 's/\\$$//' < $*.d.tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $*.d 

«Read foo.d.tmp, удалить все, вплоть до (включительно) двоеточием, удалите завершающую \, если таковой имеется. Возьмите результат и поместите каждое слово (то есть каждое необходимое условие) в свою собственную строку. Затем для каждой строки удалите ведущие пробелы, поместите двоеточие в конец и добавьте результат в foo.d. " Так что теперь foo.d содержит:

foo.o: src/foo.c src/foo.h src/bar.h 
src/foo.c: 
src/foo.h: 
src/bar.h: 

Идея заключается в том, чтобы создать пустое правило для каждого необходимого условия, так что если код изменился, и определенная предпосылка больше не нужен - и больше нет - но это все еще перечисленные в старом foo.d, Make не будет паниковать при невозможности его создания.

+4

Обратите внимание, что вам больше не нужно это с современными версиями GCC, которые предоставляют флаг '-MP', который сделает это для вас (вторая часть, во всяком случае ... не уверен, что цель первой части является). Проверьте руководство GCC, чтобы увидеть различные типы вывода, предоставляемые различными флагами '-M', и выберите те, которые вы хотите. Вероятно, вам не нужны никакие операции sed. – MadScientist

Смежные вопросы