2012-05-30 11 views
5

Powiązane: Target-specific Variables as Prerequisites in a Makefiledocelowe makefile jako warunków wstępnych

Usiłuję spreparować Makefile, który wykorzystuje zmienną docelową-specyficzne określić katalog docelowy dla plików obiektowych i końcowego pliku wykonywalnego. Chodzi o to, aby zachować dwie oddzielne wersje binarne, wersję "wydania" i wersję "debugowania" z dodatkowymi informacjami na temat debugowania.

Mój problem polega na tym, że "make" robi czystą kompilację za każdym razem, nawet jeśli niczego nie zmieniłem. Jestem prawie pewien, że dzieje się tak dlatego, że 'make' ocenia wymagania wstępne docelowych "flag" przed deklaracją zmiennych w wymaganiach wstępnych dla celu "debugowania" lub "wydania".

Plik Makefile przedstawiono poniżej.

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 

Odpowiedz

11

Przynajmniej twoja reguła kompilacji jest zepsuta. A non-phony recipe must create a target, [email protected], not $(OUTPUT_DIR)[email protected].

Należy również rozważyć konwersję zależności katalogów w wymaganiach wstępnych na order-only.

Na koniec, aby uzyskać prawidłową wartość $(OUTPUT_DIR) na liście wymagań wstępnych, należy użyć secondary expansion, ponieważ w przeciwnym razie zostanie użyta globalna definicja OUTPUT_DIR:=Test/ zamiast docelowej.

Nie wiem, jak naprawić plik Makefile bez dodatkowego rozszerzenia i magii vpath. Osobiście najpierw skonfigurowałem środowisko (dowiedzieć się wartości OUTPUT_DIR itd.), A następnie ponownie uruchom Make z odpowiednimi wartościami.

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

To jest doskonałe oczyszczanie mojego systemu budowy, dziękuję. Zauważyłem, że konieczne jest dodanie '| $ (OUTPUT_DIR) 'do listy wymagań wstępnych reguły tworzącej pliki' .o', a ja dodałem "czysty" cel, ale poza tym działa tak jak zacytowano. Wielkie dzięki. –

+0

@ Chris, oh, tak, masz rację, zapomniałem o tym (naprawiono). I nie ma za co! ;-) –

+0

Dzięki za heads up! Naprawię to teraz. –

Powiązane problemy