2010-04-26 10 views
44

C'è un modo per riassegnare il valore della variabile Makefile all'interno del corpo del target?Modifica il valore della variabile Makefile all'interno del corpo del target

Quello che sto cercando di fare è di aggiungere alcune bandiere in più per la compilazione di debug:

%.erl: %.beam 
    $(ERLC) $(ERLFLAGS) -o ebin $< 

test: clean debug_compile_flag compile compile_test 

debug_compile: 
    $(ERLCFLAGS) += -DTEST 

Quindi, se invoco prova obiettivo Vorrei ripulire il mio ambiente, aggiungere alcuni nuovi flag (come -DESTRO a quelli esistenti), compila l'intero codice ancora una volta (prime fonti, quindi moduli di test).

Non voglio copiare/incollare il codice per la compilazione con alcuni nuovi flag impostati poiché c'è molta logica messa qua e là.

C'è un modo semplice per ridefinire il valore della variabile in modo da poter riutilizzare il codice esistente?

+0

possibile duplicato del [Definire rendere variabile in fase di regola di esecuzione] (http://stackoverflow.com/questions/1909188/define-make-variabili-at-rule-esecuzione-tempo) –

risposta

-5

Edit: Come spiegato da Beta nella other answer, è possibile.


No. Non c'è modo di farlo nel Makefile. È tuttavia possibile modificare il valore di una variabile sulla riga di comando make. Se si riscrive il vostro Makefile come segue:

ERLCFLAGS += $(ERLCFLAGSADDED) 

%.erl: %.beam 
    $(ERLC) $(ERLCFLAGS) -o ebin $< 

test: clean compile compile_test 

Quindi, è possibile richiamare make per eseguire i test utilizzando:

make ERLCFLAGSADDED=-DTEST test 
+0

Sì, ho risolto il problema come lei ha suggerito, in esecuzione submake nella debug_compile: ERLC_FLAGS = $ (ERLC_DEBUG_FLAGS) $ (fARE) compilare Grazie ! – paulgray

+0

Oh sì, fantastico. Non ho pensato a questa invocazione di submake. –

+0

L'invocazione submake è ancora utile se si desidera eseguire una destinazione più volte con valori diversi dei flag. Vedi i documenti che ho citato nel commento qui sotto. – ntc2

58

sì, c'è un modo semplice per farlo, e senza rieseguire fare. Utilizzare un target-specific variable value:

test: clean debug_compile 

debug_compile: ERLCFLAGS += -DTEST 
debug_compile: compile compile_test; 
+2

L'ordine di esecuzione è garantito qui? O potrebbe un make -j2 rovinare tutto? – Marenz

+2

[Docs] (http://www.gnu.org/software/make/manual/make.html # Target_002dspecific): "Tieni presente che un determinato prerequisito verrà creato una volta sola per invocazione di make, al massimo Se lo stesso file è un prerequisito di più target e ognuno di questi ha un valore diverso per lo stesso target- variabile specifica, quindi il primo obiettivo da costruire causerà la creazione di tale prerequisito e il prerequisito erediterà il valore specifico della destinazione dal primo target, ignorando i valori specifici della destinazione da qualsiasi altro target. " – ntc2

38

Un'altra risposta è qui: Define make variable at rule execution time.

Per i più pigri, si può avere regole come le seguenti (FLAG e DEBUG sono le mie variabili):

.DBG: 
    $(eval FLAG += $(DEBUG)) 
+2

Solo la versione che ha funzionato per me, grazie! – Raphael

+1

Ho un sacco di problemi con '$ (eval xxx)', con tonnellate di strani effetti collaterali. Non sembra funzionare bene come un "vero" assegnamento della variabile Makefile. – Cyan

+0

Ho avuto un problema con la funzione 'eval' - Ho ottenuto valori vuoti per le mie variabili perché la variabile definita con eval ottiene il suo valore all'inizio dell'esecuzione del target, non quando questa linea viene raggiunta. Ad esempio, se stai creando alcuni file all'inizio del target, e successivamente provi a riempire alcune variabili usando 'eval FILES = $ (shell ls)', il tuo var FILES sarà vuoto –

0

Volevo aggiungere un target in un makefile per eseguire test, che implicava la ricompilazione del codice sorgente con alcune bandiere di debug. La risposta di Ian: https://stackoverflow.com/a/15561911/ è stata l'unica soluzione che ha funzionato.

Ecco il Makefile mi è venuta, che garantisce l'ordine di esecuzione durante l'esecuzione make tests:

TARGET  = a.out 

CC   = g++ 
GENERIC_F = -Wall -Wextra -I. -Idoctest/doctest/ 

CFLAGS  = -O0 -std=c++11 $(GENERIC_F) 
DEBUG_MODE = -DDEBUG 

LINKER  = g++ 
LFLAGS  = $(GENERIC_F) -lm 

SRCDIR  = src 
OBJDIR  = build 
BINDIR  = bin 

SOURCES = $(wildcard $(SRCDIR)/*.cc) 
INCLUDES = $(wildcard $(SRCDIR)/*.h) 
OBJECTS = $(SOURCES:$(SRCDIR)/%.cc=$(OBJDIR)/%.o) 
rm   = rm -f 

.PHONY: clear_screen tests extend_cflags 

$(BINDIR)/$(TARGET): $(OBJECTS) $(INCLUDES) 
    $(LINKER) $(OBJECTS) $(LFLAGS) -o [email protected] 
    @echo -e "Linking complete!\n" 

$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.cc $(INCLUDES) 
    @mkdir -p $(OBJDIR) $(BINDIR) 
    $(CC) $(CFLAGS) -c $< -o [email protected] 
    @echo -e "Compiled "$<" successfully!\n" 

.PHONY: clean 
clean: 
    @$(rm) $(OBJECTS) 
    @echo "Cleanup complete!" 

.PHONY: remove 
remove: clean 
    @$(rm) $(BINDIR)/$(TARGET) 
    @echo "Executable removed!" 

clear_screen: 
    @clear 

extend_cflags: 
    $(eval CFLAGS += $(DEBUG_MODE)) 

tests: | remove extend_cflags $(BINDIR)/$(TARGET) clear_screen 
    @$(BINDIR)/$(TARGET) 
Problemi correlati