2013-07-16 98 views
0

我是Makefile的新手。在試圖寫一個通用的Makefile文件可能在我的大多數與至少改造項目中使用,我遇到了一個問題(簡化爲以下):沒有規則使GNU make出現XXX錯誤

我的「項目」的模樣:

proj/ 
    src1.cpp 
    subdir1/ 
     src2.cpp 
    Makefile 

部分的Makefile

OBJ := bin/src1.o bin/subdir1/src2.o 
OBJ_DIR := bin/ bin/subdir1/ 
PROGRAMS := prog1 
define compile_template = 
$(1)/%.o: %.cpp 
    mkdir -p $$(@D) 
    $$(CXX) $$(CXXFLAGS) -c $$< -o [email protected] 
endef 

define PROGRAM_template = 
$(1): $$(OBJ) 
    $$(CXX) $$(LDFLAGS) $$^ -o [email protected] $$(LDLIBS) 
endef 

$(foreach odir,$(OBJ_DIR),$(eval $(call compile_template,$(odir)))) 
$(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog)))) 

和錯誤是:

gmake: *** No rule to make target `bin/src1.o', needed by `proj1'. Stop. 

另一個問題是我應該寫我自己的Makefile或使用automake等,如果我只編譯特定的機器(所以我有控制編譯器,操作系統,...)?

+0

這可能是一個愚蠢的答案,但你使用製表符,不是嗎?當我使用makefile時,這通常是我的麻煩來源(很久以前)。順便說一句,嘗試使用cmake – Amadeus

+0

@TomásBadan我沒有使用標籤。 cmake似乎是一個不錯的選擇,謝謝你! – GuLearn

回答

3

調試此類問題(eval的問題)的最佳方法是用$(info ...)的調用替換$(eval ...)函數。這將打印出解析的文本,通常很明顯你的問題是什麼。如果你重寫你的eval線這樣的:

$(foreach odir,$(OBJ_DIR),$(info $(call compile_template,$(odir)))) 
$(foreach prog,$(PROGRAMS),$(info $(call PROGRAM_template,$(prog)))) 

(和修復您的明顯的語法錯誤,在第一線:=之間的空間)你看:

bin//%.o: %.cpp 
     mkdir -p $(@D) 
     $(CXX) $(CXXFLAGS) -c $< -o [email protected] 
bin/subdir1//%.o: %.cpp 
     mkdir -p $(@D) 
     $(CXX) $(CXXFLAGS) -c $< -o [email protected] 
prog1: $(OBJ) 
     $(CXX) $(LDFLAGS) $^ -o [email protected] $(LDLIBS) 

從這裏就可以看出prog1取決於bin/src1.obin/subdir1/src2.o所以要製作bin/src1.o。它看起來通過你的規則,但在make的內部匹配語法bin//%.o確實不是匹配bin/src1.o因爲額外的斜槓。

更改您的任務刪除尾隨斜線和它應該更好地工作:

OBJ_DIR := bin bin/subdir1 
+0

非常感謝!在你提到之前,我不知道函數'info'。 +1! – GuLearn