2012-05-30 19 views
5

correlati: Target-specific Variables as Prerequisites in a Makefilebersaglio makefile come prerequisiti

Sto cercando di predisporre un Makefile che utilizza una variabile specifica target per specificare la directory di output per i file oggetto e l'eseguibile finale. L'idea è di mantenere due versioni binarie separate, una versione 'release' e una versione 'debug' con informazioni di debug aggiuntive.

Il mio problema è che "make" crea una build pulita ogni volta, anche se non ho cambiato nulla. Sono abbastanza sicuro che è perché "make" sta valutando i prerequisiti dei "corewars" di destinazione prima della dichiarazione della variabile nei prerequisiti per il target "debug" o "release".

Il file Makefile è presentato di seguito.

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 

risposta

11

Almeno la regola di compilazione è interrotta. A non-phony recipe must create a target, [email protected], not $(OUTPUT_DIR)[email protected].

Considerare inoltre la conversione delle dipendenze di directory nei prerequisiti order-only.

Infine, per ottenere il valore corretto del $(OUTPUT_DIR) all'interno della lista di prerequisiti, è necessario utilizzare secondary expansion, perché altrimenti, la definizione globale OUTPUT_DIR:=Test/ viene utilizzato al posto di uno specifico target.

Non so, come riparare il Makefile senza espansione secondaria e vpath magic. Personalmente dovrei prima configurare l'ambiente (scoprire il valore di OUTPUT_DIR, ecc.) E quindi rieseguire Esegui con i valori corretti.

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

Questa è un'eccellente sanificazione del mio sistema di costruzione, grazie. Ho trovato necessario aggiungere '| $ (OUTPUT_DIR) 'all'elenco dei prerequisiti affinché la regola crei i file' .o' e ho aggiunto un target 'pulito', ma a parte questo funziona come indicato. Grazie molto. –

+0

@Chris, oh, sì, hai ragione, me ne sono dimenticato (risolto). E tu sei il benvenuto! ;-) –

+0

Grazie per l'attenzione! Lo aggiusterò ora. –

Problemi correlati