2012-10-12 34 views
10

我使用gmake和gcc -MM跟蹤標頭依賴關係,跟在the manual之後。該機制依賴於makefile include指令來導入計算的依賴關係。GNU make:乾淨目標取決於包括

由於生成文件包含.d文件,因此它們必須存在才能生成任何目標,包括clean。所以clean之前可以做正確的事情,必須生成依賴關係,如果一個失敗,然後clean只是做得更亂。

除了clean,它希望在構建任何目標之前創建所有的依賴關係。此外,如果任何文件被更改爲包含不存在的文件,則依賴關係解析會中斷,並且根本不會生成任何文件。

如果刪除標題,那麼現有的依賴項文件仍然將其命名爲目標文件,在除去違規的依賴文件之前不會生成任何內容......這不能通過clean完成。

用通配符替換include的替換模式以包含所有先前存在的依賴文件可解決一些問題,但它仍無法清除已損壞的依賴項,並且永不刪除過時的依賴項文件。有更好的解決方案嗎?手冊的示例是否真正用於實際使用?

回答

15

只是不提供生成.d文件的規則。關於爲什麼它不那麼好的一個很好的解釋(包括你的情況)可以在Paul Smith的"Advanced Auto-Dependency Generation"中找到 - 它是GNU Make的維護者。

概括地說,下面的模式工作正常,我對所有情況:

CPPFLAGS += -MMD -MP 

%.o: %.c 
    $(CC) $(CPPFLAGS) $(CFLAGS) -o [email protected] -c $< 

-include $(OBJS:.o=.d) 

參見我以前的相關答案:

+0

@Patatoswatter,no。在這種情況下,.d文件的生成與實際編譯相結合,GCC在單個調用中執行這些步驟。 –

+0

對不起,在閱讀更多內容之前我不應該說話。看起來像'-MP'解決了什麼問題後解決了剩餘的問題。但我更喜歡將對象從源保存在另一個目錄中,並且可能需要對依賴文件進行更多處理以支持預編譯頭。 – Potatoswatter

+0

@Patatoswatter,我從來沒有使用過PCH,但是爲對象和源分割目錄不是一個大問題。只需將路徑前綴爲目標和前提條件:'$(OBJ_DIR)/%。o:$(SRC_DIR)/%。c'。依賴文件將放置在'$(OBJ_DIR)'中的目標文件附近。 –

2

我通常的模式看起來像

all: target 
target: .depends 

## [snip build rules] 

.depends: 
    gcc -MM $(CPPFLAGS) .... > [email protected] 

-include .depends 

-include而不是include。基本上,它包括有條件的:即當且僅當文件存在

查看文檔:http://www.gnu.org/software/make/manual/make.html#Include

+0

+1:將固定眼前的問題減號。謝謝,現在我指出了正確的方向...... – Potatoswatter

+4

這是次優的,沒有必要有一條規則來生成依賴關係。作爲編譯的副產品,更好地生成依賴關係。對於第一個編譯依賴是不必要的,因爲每個源都需要被構建。只有後續版本需要依賴關係,並且它們是由以前的版本生成的。 –

+0

@MaximYegorushkin我每天都在學習。尼斯。 (我也讀過其他答案:)) – sehe