2017-01-28 16 views
3

我正在嘗試編寫一個makefile,它能夠確定何時更改了標頭,然後重新編譯相應的.cpp文件。爲了測試這個,我創建了三個文件:main.cppa.hb.hmain.cpp包括s a.ha.h包括b.h使相同的Makefile中的make目標之間的遞歸依賴關係

我的makefile文件看起來是這樣的:

prog: main.cpp a.h 
     g++ main.cpp -o prog 

a.h: b.h 

a.hb.h,並且main.cpp任意組合改變,我希望prog重新編譯。儘管如此,只有當a.hmain.cpp發生更改時,prog纔會重新編譯,最後一行似乎被忽略。

我在做什麼錯誤,我怎麼能做到我想要的東西不加入全面和完整的套頭像這樣每個人.cpp文件(因爲對於規模較大的項目,這可能成爲極其繁瑣):

prog: main.cpp a.h b.h 
     g++ ... 
+0

添加這行'a.h:b.h'的目的是什麼?你想說'a.h'依賴於'b.h'嗎?如果是的話,a.h'#inlcude b.h'? – Rishi

+0

可能的重複:https://stackoverflow.com/questions/2394609/makefile-header-dependencies https://stackoverflow.com/questions/15857837/compile-headers-dependencies-with-makefile https://stackoverflow.com/問題/ 297514 /如何,我有一個makefile文件,自動重建源文件,包括一個莫迪 – celtschk

+0

@Rishi你是對的啊,包括bh – john01dav

回答

6

我在做什麼錯誤

您的規則:

a.h: b.h 

只是告訴makea.h取決於b.h,即該a.h將需要 (重新)製成,以任何方式make可以從生成文件確定,如果 a.h是年齡超過b.h或不存在。

它不會告訴make做什麼b.h重拍a.h。您的生成文件 不包含配方用於從b.h重新制作a.h。它僅包含一個配方 從main.cppa.h改造prog,即:

prog: main.cpp a.h 
     g++ main.cpp -o prog 

而且make,當然,有一個配方沒有內置規則使 a.hb.h。因此,在沒有任何製作a.h的配方b.h 它假定這種依賴需要沒有什麼可做的。沒有其他合理的默認值 。因此,即使a.hb.h舊,也沒有做到a.h;儘管prog取決於a.h,但在該帳戶上不需要執行 至prog

這是幸​​運的,因爲其實你不想a.h在 任何方式任何時候b.h變化重拍,而你不想main.cpp以任何方式任何時候a.hb.h 重拍變化。當你想要prog當它們中的任何一個改變時重新制作 。

prog: main.cpp a.h b.h 
    g++ main.cpp -o prog 

prog: main.cpp a.h 
    g++ main.cpp -o prog 

prog: b.h 

prog: main.cpp b.h 
    g++ main.cpp -o prog 

prog: a.h 
:你想要的是由任何 以下的makefile的表達

prog: main.cpp 
    g++ main.cpp -o prog 

prog: a.h b.h 

prog: main.cpp 
    g++ main.cpp -o prog 

prog: a.h 
prog: b.h 

(和更多一些)。它們都是等價的。他們都說prog取決於 上main.cppa.hb.h,他們都這樣說是必須要做的,每當 prog需要重拍,即:

g++ main.cpp -o prog 

我怎麼能做到我想要的東西不添加充分和完整的 頭像這樣 每個單獨的.cpp文件(因爲對於規模較大的項目,這可能成爲非常麻煩)

事實上,GCC編譯器在很長一段時間內會產生一個用於生成迷你Makefiles的功能,該迷你Makefiles表示 每個頭文件將生成的目標文件的依賴關係讀取爲了使目標文件。 GNU make可以利用此功能 生成那些相關性文件並將它們包含在用於構建GCC目標的makefile中。 GCC和make之間的這種合作稱爲自動相關性生成(或類似的)。 如何在makefile中執行該操作的問題是this one 的重複,如果您是谷歌,例如「gcc自動生成依賴關係」,你也可以找到古魯的治療方法。

在評論你的建議,你是不是還不夠專家GNU 化妝有信心與自動依存產生技術,those answers所示 。那麼,你 可以開始得到了它的竅門有一個基本的實現簡單 ,因爲這(這也使得在其他方面makefile文件更加正常):

的Makefile

.PHONY: all clean 

all: prog 

prog: prog.o 

prog.o: main.cpp 
    g++ -MMD -c -o prog.o main.cpp 

prog: prog.o 
    g++ -o prog prog.o 

clean: 
    rm -f prog *.o *.d 

-include prog.d 

-MMD是GCC預處理器選項,用於生成依賴文件 prog.d。這裏是the documentation of -MMD

prog.d是一個小型的Makefile:

$ cat prog.d 
prog.o: main.cpp a.h b.h 

表達所有的prog.o的依賴。第一次運行, include -ed makefile prog.d將不存在,這將是一個致命的make 錯誤,但事實上,-前綴告訴make忽略該錯誤。 所以make收益和一切,包括prog.d被提出,此後 prog.d將被重新生成,只要任何規則 - 包括prog.d 本身的規則 - 要求prog.o重新編譯。