2012-05-30 51 views
5

相關:Target-specific Variables as Prerequisites in a Makefile的makefile目標特定變量作爲先決條件

我想這手藝使用特定目標變量指定的輸出目錄的對象文件和最終的可執行一個Makefile。我們的想法是維護兩個獨立的二進制版本,一個「發佈」版本和一個帶有額外調試信息的「調試」版本。

我的問題是'make'每次都做一個乾淨的構建,即使我沒有改變一件事情。我非常確定這是因爲'make'正在評估'debug'或'release'目標的先決條件中變量聲明之前目標'corewars'的先決條件。

Makefile如下所示。

CXX=g++ 
LD=g++ 
LDFLAGS= 
CXXFLAGS=-Iinclude -Wall -Wextra 
OBJECTS=main.o Machine.o Core.o ProcessQueue.o Instruction.o 
OUTPUT_DIR:=Test/ 

.PHONY: default 
.PHONY: all 
.PHONY: release 
default: release 
all: release 
release: OUTPUT_DIR:=Release/ 
release: corewars 

.PHONY: debug 
debug: CXXFLAGS+=-DDEBUG -g 
debug: OUTPUT_DIR:=Debug/ 
debug: corewars 

corewars: $(OUTPUT_DIR) $(addprefix $(OUTPUT_DIR),$(OBJECTS)) 
    $(LD) -o $(addprefix $(OUTPUT_DIR),corewars) $(addprefix $(OUTPUT_DIR),$(OBJECTS)) 

Release: 
    mkdir -p [email protected] 
Debug: 
    mkdir -p [email protected] 

%.o: %.cpp include/%.h 
    $(CXX) -c $(CXXFLAGS) $< -o $(OUTPUT_DIR)[email protected] 


.PHONY: clean 
clean: 
    $(RM) -r Release 
    $(RM) -r Debug 

回答

11

至少您的編譯規則已損壞。 A non-phony recipe must create a target, [email protected], not $(OUTPUT_DIR)[email protected].

還要考慮將目錄依賴關係轉換爲order-only先決條件。

最後,要獲取$(OUTPUT_DIR)在先決條件列表中的正確值,必須使用secondary expansion,否則將使用全局定義OUTPUT_DIR:=Test/而不是特定於目標的定義。

我不知道,如何解決你的Makefile沒有二次展開和vpath的魔法。我個人首先設置環境(找出OUTPUT_DIR等的值),然後用適當的值重新執行Make。

ifndef OUTPUT_DIR 

.PHONY: default all release debug 

default all: release 

release: export OUTPUT_DIR := Release/ 
debug: export OUTPUT_DIR := Debug/ 
debug: export EXTRA_CXXFLAGS := -DDEBUG -g 

release debug: 
    @$(MAKE) 

else 

# ... 
CXXFLAGS := -Iinclude -Wall -Wextra $(EXTRA_CXXFLAGS) 

PROGRAM := $(OUTPUT_DIR)corewars 
OBJECTS := $(addprefix $(OUTPUT_DIR), \ 
    main.o Machine.o Core.o ProcessQueue.o Instruction.o) 

# Default target. 
$(PROGRAM): $(OBJECTS) | $(OUTPUT_DIR) 
    $(LD) -o [email protected] $< 

$(OUTPUT_DIR)%.o: %.cpp | $(OUTPUT_DIR) 
    $(CXX) -c $(CXXFLAGS) $< -o [email protected] 

$(OUTPUT_DIR): 
    mkdir -p [email protected] 

endif # OUTPUT_DIR 
+0

這是我的構建系統的一個很好的sanitisation,謝謝。我發現有必要添加'| $(OUTPUT_DIR)'作爲制定'.o'文件的規則的先決條件列表,並且我添加了一個'clean'目標,但除此之外,它的工作方式與引用相同。非常感謝。 –

+0

@克里斯,哦,是的,你是對的,我忘了它(固定)。不客氣! ;-) –

+0

感謝您的領導!我現在要解決這個問題。 –

相關問題