2009-12-30 58 views
6

我是新來的Makefile和g ++,我同時使用-MM標誌項目文件的生成依賴的一個問題擊中。我正在發佈我正在使用的Makefile以供您考慮。請看一下。使用問題產生Makefile中的依賴-MM

OUTPUT_ROOT := output/ 
SOURCE_ROOT := source/ 

TITLE_NAME := TestProj 

SOURCES := \ 
MyFile.cpp \ 
stdAfx.cpp \ 
Main.cpp \ 

OUT_DIR := $(OUTPUT_ROOT) 

OUT_O_DIR := $(OUT_DIR) 

OBJS = $(SOURCES:%.cpp=$(OUT_O_DIR)%.o) 
DEPS = $(OBJS:%.o=%.d) 
DIRS = $(subst /,/,$(sort $(dir $(OBJS)))) 
SOURCE_TARGET = $(SOURCES:%.cpp=$(SOURCE_ROOT)%.cpp) 
OUTPUT_TARGET = $(OUT_DIR)$(TITLE_NAME) 

#--------------------------------------------------------------------- 
# executables 
#--------------------------------------------------------------------- 
MD := mkdir -p 
RM := rm 
CC := g++ 

#--------------------------------------------------------------------- 
# rules 
#--------------------------------------------------------------------- 
.PHONY: clean directories objects title 

all: directories objects title 

directories: 
@$(MD) $(DIRS) 

clean: 
$(RM) -rf $(OUT_DIR) 

$(OBJS): $(SOURCE_TARGET) 
@$(CC) -c $< -o [email protected] 

$(DEPS): $(SOURCE_TARGET) 
@$(CC) -c -MM $< > $(DEPS) 

-include $(DEPS) 

objects:$(OBJS) $(DEPS) 

title: $(OBJS) 
@$(CC) $< -o [email protected] 

我嘗試了幾個選項,sooo很多次。我搜索瞭解決方案,但找不到任何。

是使用「-MM」標誌,以生成依賴正確的選擇?如果不是,請給我建議正確的方法來生成依賴關係。我想自動生成依賴關係,因爲我的項目會有很多文件。我認爲這是比手動編寫evey依賴關係更好的選擇。

這是我收到提前

g++: stdAfx.d: No such file or directory 
g++: Main.d: No such file or directory 
make: *** No rule to make target `stdAfx.d', needed by `objects'. Stop. 

感謝錯誤。

+0

什麼是「DEPS = $(OBJS:%。o =%。d)」應該是在做什麼?爲什麼你有時使用':=',有時'='? – 2009-12-30 12:23:12

+0

它使用對象目錄中對象的名稱創建DEPS。我只是測試'='和':='選項,但不知道確切的差異b/w他們 – Jabez 2009-12-30 12:27:08

回答

8

它看起來像你想生成依賴文件(稱爲* .D,通過你的Makefile規則)爲每個.cpp文件。這不是我對如何使用依賴關係文件的理解。

使用-M選項生成您的項目單一依賴文件,然後包括依賴文件。

DEPS = $(OUR_DIR)/make.dep 

$(DEPS): $(SOURCE_TARGET) 
    @$(CC) -M $(SOURCE_TARGET) > $(DEPS) 

include $(DEPS) 

編輯你的依賴文件也應該取決於你的頭

$(DEPS): $(SOURCE_TARGET) $(HEADER_TARGET) 
    @$(CC) -M $(SOURCE_TARGET) > $(DEPS) 

其中HEADER_TARGET定義一樣SOURCE_TARGET。這樣,當頭文件被改變時,依賴文件被重建。

+1

謝謝mcdave,這是一個非常好的技巧。我認爲生成單個文件比生成很多...再次感謝您 – Jabez 2009-12-30 13:53:38

+1

只需指出'-MM'排除了系統頭文件(或多或少),因爲分配的文件比較少,所以可能會使編譯速度更快1)檢查2)構建依賴列表的過程。例如用一些stl include創建foo.cpp包含並運行'g ++ -M foo.cpp'來查看它吐出一個近100個依賴關係的列表,其中沒有任何一個會發生變化,所有這些都將檢查每個構建。 – 2010-05-10 08:40:30

+0

@Robert:感謝您的提示 - 我不知道這一點,並會更新我的makefiles,使它們更有效率! – mcdave 2010-05-10 12:16:14

3

對於初學者,你正在做一些異國情調的東西。你應該從簡單開始,只使用你100%理解和信任的Makefile中的代碼。即使在擁有數百個文件的大型項目中,您也不會花太多時間來維護Makefile。

與指派變量:=立即被展開 - 所有$(VAR)的值代入分配期間的變量的值。分配給=的變量在使用時展開,因此它們可以執行諸如引用尚未定義的變量之類的事情。

關於g的-MM標誌++會生成一個生成文件依賴行,例如foo.o:foo.cc foo.hh,但我從未發現它有用。我有一個虛假的「依賴」目標,生成一個依賴文件。你用這些線依賴關係創建一堆* .d文件的想法可能會奏效,但最終你會得到很多這些文件。

你得到的錯誤是來自g ++,而不是來自make。這是因爲當$(DEPS)是整個* .d文件列表時,它就像是單個文件一樣。什麼情況是這一行:

@$(CC) -c -MM $< > $(DEPS) 

被擴展爲:

g++ -c -MM MyFile.cpp > MyFile.d stdAfx.d Main.cpp 

mcdave剛剛發佈我用生成的依賴文件的代碼。您可以切換到單一依賴文件風格,或者改變你-MM命令是:

@$(CC) -MM $< > [email protected] 

您可能還需要修復-include說法,因爲我不認爲它支持的文件到列表做包括。

+0

謝謝你,我現在使用單個文件,而不是許多多個文件。謝謝你告訴比較b/w'='和':=',這肯定幫助我很多。 – Jabez 2009-12-30 13:51:54