2012-05-30 6 views
5

Verwandte: Target-specific Variables as Prerequisites in a MakefileMake-Datei zielspezifische Variablen als Voraussetzungen

Ich versuche, ein Makefile zu fertigen, die ein zielspezifische-Variable verwendet das Ausgabeverzeichnis für die Objektdateien und die endgültigen ausführbaren Datei angeben. Die Idee besteht darin, zwei separate Binärversionen zu unterhalten, eine "Release" -Version und eine "Debug" -Version mit zusätzlichen Debugging-Informationen.

Mein Problem ist, dass 'make' jedes Mal ein sauberes Build erstellt, auch wenn ich nichts geändert habe. Ich bin mir ziemlich sicher, dass es ist, weil 'make' die Voraussetzungen des Ziels 'corewars' vor der Variablendeklaration in den Voraussetzungen für das 'debug' oder 'release' Ziel auswertet.

Das Makefile ist unten dargestellt.

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 

Antwort

11

Zumindest ist Ihre Kompilierungsregel gebrochen. A non-phony recipe must create a target, [email protected], not $(OUTPUT_DIR)[email protected].

Beachten Sie auch die Konvertierung von Verzeichnisabhängigkeiten in order-only Voraussetzungen.

schließlich den richtigen Wert von $(OUTPUT_DIR) in der Liste der Voraussetzungen zu erhalten, müssen Sie secondary expansion, verwenden, da sonst OUTPUT_DIR:=Test/ die globale Definition statt zielspezifische eines verwendet wird.

Ich weiß nicht, wie Sie Ihr Makefile ohne sekundäre Erweiterung und Vpath Magie zu beheben. Persönlich würde ich zuerst die Umgebung einrichten (finde den Wert von OUTPUT_DIR, etc.) und führe dann Make mit den richtigen Werten erneut aus.

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

Dies ist eine ausgezeichnete Sanitisierung meines Build-Systems, danke. Ich fand es notwendig, '| hinzuzufügen $ (OUTPUT_DIR) 'in die Liste der Voraussetzungen für die Regel, um' .o' Dateien zu machen, und ich habe ein 'sauberes' Ziel hinzugefügt, aber ansonsten funktioniert das wie zitiert. Danke vielmals. –

+0

@Chris, oh ja, du hast Recht, ich habe es vergessen (behoben). Und gern geschehen! ;-) –

+0

Danke für die Köpfe hoch! Ich werde das jetzt reparieren. –

Verwandte Themen