Makefile備忘錄

#1.兩種依賴關係

如果出現這種形式的依賴關係 a : b | c,其中a和b是常見的依賴關係,主要包括兩個方面:,一個是b必須在a之前生成,另一個則是如果b比a新,則a必須重新生成。而a和c的依賴關係則比較特殊,是一種順序依賴,也就是c必須要在a之前生成,但c是否比a新並不影響是否需要重新生成a。

關於哪些場景下會需要a和c之間的這種依賴關係,我舉個例子來說明下,比如a.o依賴a.cpp,並且你需要a.o存放在目錄build下面,那麼你可以這樣寫,a.o : a.cpp | build,這樣就能夠保證build在你生成a.o之前是存在的,並且如果在build目錄下添加了文件或做了其他會修改目錄build的timestamp的操作時,並不會導致a.o的重新生成。

下面是截圖自gnu make手冊的關於這種關係的講解。

#2.自動生成依賴關係

一般寫小型項目時,我們纔會手動把各個文件之間的依賴關係寫出來,但是當項目稍微大些時,手動寫不僅麻煩而且容易出錯或寫漏,更重要的是如果你後面修改文件導致依賴關係也發生改變,還必須再次修改makefile文件。

我們可以利用g++的一些編譯選項來幫助我們自動生成依賴關係,下面我舉個例子來說明下:

我們有a.cpp文件,這個文件include幾個頭文件,包括a.h,b.h,c.h,我們可以在makefile中這樣寫:

a.o: a.cpp 
    g++ a.cpp -c -o a.o -MMD $(CFLAGS)
-include a.d
選項-MMD會將依賴關係保存在文件a.d(該文件名字由-o指定的文件名後綴改成.d得到),-include的表示即使文件不存在也不出錯,因爲在第一次運行makefile文件時,a.d文件是不存在的所以我們需要使用-include而不是include。同時也因爲第一次運行時a.o文件是不存在的,所以語句g++ a.cpp -c -o a.o -MMD $(CFLAGS)是肯定會被執行的,並且會產生依賴文件a.d,a.d的內容如下:

a.o: a.cpp a.h b.h c.h
那麼在之後運行這個makefile文件時,a.d文件已經存在了,所以-include a.d會把a.d的內容包含在makefile文件中,此時a.o的多行依賴目標(makefile中的和include進來的a.d中的)會合併到一起,也就是相當於是將makefile的內容變成了

a.o: a.cpp a.h b.h c.h
    g++ a.cpp -c -o a.o -MMD $(CFLAGS)
此時任何一個文件(a.cpp,a.h,b.h,c.h)修改了,a.o都會被重新生成,於是我們就達成了讓makefile自動生成依賴關係的目標啦。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章