2012-08-07 28 views
11

我知道下面的makefile會讓預處理器自動生成依賴項(在.d文件中)並將它們包含在makefile中(因爲我的課程筆記會這麼說),所以他們不必自動維護。 -MMD標誌是對此負責的。我沒有得到的是:什麼時候生成的.d文件?甚至沒有使用${CXXFLAGS}的任何命令。據推測,像${CXX} ${CXXFLAGS} -c x.C -o x.o這樣的命令將被make自動推斷爲每個目標文件,但是如果這些是生成.d文件的命令,我們是不是已經通過了知道xo,yo和zo依賴關係的點如果我們只通過執行生成這些.o文件的命令來了解它們,它們可能是相關的嗎? (說有.h文件,如果留下來推斷其本身或某事規則的生成文件會忽略。)在makefile中使用g ++和-MMD來自動生成依賴關係

CXX = g++      # compiler 
CXXFLAGS = -g -Wall -MMD  # compiler flags 
OBJECTS = x.o y.o z.o   # object files forming executable 
DEPENDS = ${OBJECTS:.o=.d} # substitutes ".o" with ".d" 
EXEC = a.out     # executable name 

${EXEC} : ${OBJECTS}   # link step 
    ${CXX} ${OBJECTS} -o ${EXEC} 

-include ${DEPENDS}   # copies files x.d, y.d, z.d (if they exist) 

回答

8

據推測,命令,如${CXX} ${CXXFLAGS} -c x.C -o x.o會爲每個物體的自動推斷文件,但如果這些是生成.d文件的命令,我們是不是已經通過了知道xo,yo和zo的依賴關係可能相關的點,如果我們只通過執行命令生成這些.o文件?

你在這裏是正確的。第一次運行Makefile時,依賴關係不存在。

但是這並不重要 - 只有當.o文件已經存在,並且您已經更改.h文件時才需要依賴信息。第一次運行Make時,無論如何都需要構建所有.o文件,並且同時生成.d文件。

之後,.d文件將提供相關性信息。如果標題改變了,依賴信息會告訴Make哪個.o文件需要重建。如果源文件發生更改,那麼.o將始終需要重建,並且會同時生成更新的依賴關係信息。

1

如果您想知道背後的makefile文件正在做什麼,請使用-p標誌,並將輸出重定向到一個文件,因爲它是一大堆東西。

make -p foo > bar將轉儲出make foo的所有變量值和規則,然後查看bar將顯示爲隱式規則運行的命令。在你的情況下,它會告訴你,.cpp.o%.o: %.cpp(奇怪的是,他們都在那裏)規則將調用$(COMPILE.cpp)它解析爲$(COMPILE.cc)它解析爲$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c。其中有一個有趣的屬性,您可以將其添加到CXXFLAGS或CPPFLAGS中以將它們放入.cpp.o編譯中,但不包含僅由.c.o規則使用的CFLAGS,這樣做有點意義,因爲您可能需要C文件和C++文件的處理方式不同(CC和CXX通常也設置爲不同的編譯器)。

0

是的,你說得對,如果你刪除了依賴文件,但是保留了對象文件,那麼make會運行不完整的依賴信息,並且可能無法重新構建其頭文件已經改變的對象文件。

Make也可能拒絕構建 - 當依賴文件引用已刪除的頭(並且明顯不再引用其他來源)時,會發生這種情況。由於Make不知道如何在編譯之前重新生成依賴項文件,它只能報告一個缺失的依賴項(然後顯而易見的操作是去除依賴項文件,導致上面的第一個條件)。

對此的唯一答案是紀律:當刪除依賴文件時,總是刪除對象文件。您可以使用clean目標來解決此問題。

clean:: 
     $(RM) *.o *.d 

或者另外,告訴製作如何創建依賴文件:

%.dep: %.cc 
     $(CXX) -MM $(CPPFLAGS) $< | sed -e 's,\($*\)\.o[ :]*,\1.o [email protected]: ,g' > [email protected] 

(該sed命令可以確保依賴本身依賴於作爲對象文件做同樣的來源)。