2013-04-07 23 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

假設你正在構建從src/foo.cobj/foo.o,因此該文件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 

「讀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 2013-04-07 20:07:14