2016-09-18 58 views
1

我是新來的makefile,並試圖瞭解一些代碼:的Makefile說明

%.o:%.c 
    $(CC) $^ -c -Wall 
    $(CC) -MM $*.c > $*.dep 
    $(OBJECTDUMP) -d -M intel -S [email protected] 
    @mv -f $*.dep $*.dep.tmp 
    @sed -e 's|.*:|$*.o:|' < $*.dep.tmp > $*.dep 
    @sed -e 's/.*://' -e 's/\\$$//' < $*.dep.tmp | fmt -1 | \ 
     sed -e 's/^ *//' -e 's/$$/:/' >> $*.dep 
    @rm -f $*.dep.tmp 

能有人請解釋一下最後5行代碼在做什麼?

+1

它們通過'gcc -MM'調用重新格式化依賴項輸出問題。爲了什麼? dunno ... –

回答

4

那些行的目的是處理與依賴性處理的一個問題。

假設你有一個頭文件bar.h,幷包含行

#include "bar.h" 

現在生成依賴文件中的源文件foo.c

$(CC) -MM $*.c > $*.dep 

文件foo.dep現在包含:

foo.o: foo.cc bar.h 

很好。我確定makefile有一行,如-include *.dep,所以現在Make會正確處理foo的依賴關係。但是現在假設你編輯foo.c,刪除那條#include行,並刪除不再需要的bar.h。下次您嘗試make foo時,Make會讀取舊foo.dep,其中要求bar.h,請參閱沒有這種標題,也沒有已知的方式來構建它,然後中止。在重建dep文件之前,make不會知道這個頭文件是不需要的,因爲頭文件缺失並且Make認爲它是需要的,所以它不能這樣做。

一種解決方法是刪除foo.dep,當出現這種情況(請中止之前,如果可能的話)。另一種是添加一條線到foo.dep

bar.h: 

這將安慰使得對缺少標題的擔憂。第一種方法需要人工關注,第二種方法可以自動化:第二種方法可以自動化:

@mv -f $*.dep $*.dep.tmp # rename foo.dep -> foo.dep.tmp 
@sed -e 's|.*:|$*.o:|' < $*.dep.tmp > $*.dep # this does nothing and appears to be vestigal 
@sed -e 's/.*://' \ # remove the target, leaving foo.c bar.h 
    -e 's/\\$$//' \ # remove line continuation marks, if any 
    < $*.dep.tmp | fmt -1 | \ # put each word on its own line 
    sed -e 's/^ *//' \ # remove leading whitespace 
    -e 's/$$/:/' \ # add a colon to the end of each line (making it a rule) 
    >> $*.dep # save the result as foo.dep 
@rm -f $*.dep.tmp # delete the temporary file 
+0

GCC選項'-MP'也解決了這個問題,而不需要'sed' jiggery-pokery。 – user657267

+0

@ user657267:非常真實。 jiggery-pokery早於該選項,該選項被實施以使其不必要。 – Beta

3

$*大致對應於在第一行中的%

  • @mv線移動舊basename.dep文件basename.dep.tmp
  • 第一@sed線編輯什麼是在basename.dep.tmp,與basename.o:更換任何東西,以冒號(因爲$*make擴大,而不是shell) 。
  • 第二行@sed行和下面的行做了一些更多的編輯 - 將basename.dep.tmp文件的另一個變體附加到basename.dep的末尾。
  • @rm行刪除臨時文件basename.dep.tmp

第二sed序列的更透徹的分析,需要一個什麼樣的在.dep文件,正是fmt -1爲您做更詳細的瞭解。

但是,似乎我們的目標是要更新應用到源文件的依賴關係的基礎上,從編譯器的信息,加上以適應程序員的方式按摩它。爲什麼不明白我。