Posso passare variabili a un Makefile GNU come argomenti della riga di comando? In altre parole, voglio passare alcuni argomenti che diventeranno variabili nel Makefile.Passaggio di variabili aggiuntive dalla riga di comando per rendere
risposta
Sono disponibili diverse opzioni per impostare le variabili dall'esterno makefile:
Da ambiente - ogni variabile d'ambiente si trasforma in una variabile makefile con lo stesso nome e valore.
Si consiglia inoltre di impostare
-e
opzione (aka--environments-override
), e le variabili d'ambiente si ignorare le assegnazioni fatte in makefile (a meno che queste assegnazioni si usano iloverride
directive. Tuttavia, non è raccomandato, ed è molto meglio e flessibile per utilizzare?=
assegnazione (l'operatore di assegnazione variabile condizionale, ha effetto solo se la variabile non è ancora definita):FOO?=default_value_if_not_set_in_environment
noti che alcune variabili non vengono ereditate dall'ambiente:
MAKE
è ottenuto dal nome dello scriptSHELL
si sia impostata all'interno di un makefile, o default/bin/sh
(logica: i comandi sono specificati all'interno del makefile, e sono shell-specifico).
da linea di comando-
make
può richiedere assegnazioni di variabili come parte della sua linea di comando, si mescolava con gli obiettivi di:make target FOO=bar
Ma poi tutte le assegnazioni a
FOO
variabile all'interno del makefile saranno ignorati a meno che non si utilizzi looverride
directive nell'assegnazione. (L'effetto è lo stesso dell'opzione-e
per le variabili di ambiente).Esportazione dal genitore Fai - se si chiama Fare da un Makefile, di solito non si dovrebbe scrivere in modo esplicito le assegnazioni delle variabili come questo:
# Don't do this! target: $(MAKE) -C target CC=$(CC) CFLAGS=$(CFLAGS)
Invece, soluzione migliore potrebbe essere quella di esportare queste variabili . L'esportazione di una variabile lo rende nell'ambiente di ogni invocazione di shell, e Crea chiamate da questi comandi seleziona queste variabili d'ambiente come specificato sopra.
# Do like this CFLAGS=-g export CFLAGS target: $(MAKE) -C target
È inoltre possibile esportare tutte le variabili utilizzando
export
senza argomenti.
Il modo più semplice è:
make foo=bar target
Poi, nel tuo makefile si può fare riferimento a $(foo)
. Nota che questo non si propagherà automaticamente alle sub-marche.
Se si utilizza sotto-marche, leggi questo articolo: Communicating Variables to a Sub-make
di sotto-ti intendi per i makefile 'inclusi' nel makefile principale? – Pablo
@ Michael: Significa richiamare make dall'interno del makefile. Ho aggiornato la mia risposta poiché sembra che tu sia interessato a questo dettaglio. –
Diciamo che avete un makefile come questo:
action:
echo argument is $(argument)
Si potrebbe quindi chiamare make action argument=something
Dal manual:
Le variabili nella marca possono provenire da l'ambiente in cui viene eseguito make. Ogni variabile d'ambiente che make vede all'avvio viene trasformata in una variabile make con lo stesso nome e valore. Tuttavia, un'assegnazione esplicita nel makefile, o con un argomento di comando, sovrascrive l'ambiente.
così si può fare (da bash):
FOOBAR=1 make
risultante in una variabile FOOBAR
nel Makefile.
Se si commette un file chiamato Makefile e aggiungere una variabile come questo $ (unittest) allora si sarà in grado di utilizzare questa variabile all'interno del Makefile anche con caratteri jolly
esempio:
make unittest=*
io uso BOOST_TEST e dando un jolly per il parametro --run_test = $ (unittest) allora sarò in grado di utilizzare espressioni regolari per filtrare il test voglio che il mio Makefile per eseguire
C'è un'altra opzione non citata qui che è inclusa nel libro GNU Make di Stallman e McGrath (vedere http://www.chemie.fu-berlin.de/chemnet/use/info/make/make_7.html). Esso fornisce l'esempio:
archive.a: ...
ifneq (,$(findstring t,$(MAKEFLAGS)))
+touch archive.a
+ranlib -t archive.a
else
ranlib archive.a
endif
essa comporta la verifica se un dato parametro appare in MAKEFLAGS
. Ad esempio .. supponiamo che tu stia studiando i thread in C++ 11 e hai diviso il tuo studio su più file (class01
, ..., classNM
) e vuoi: compilare poi tutto ed eseguirlo individualmente o compilarne uno alla volta ed eseguirlo se viene specificato un flag (-r
, ad esempio).Quindi, si potrebbe venire con il seguente Makefile
:
CXX=clang++-3.5
CXXFLAGS = -Wall -Werror -std=c++11
LDLIBS = -lpthread
SOURCES = class01 class02 class03
%: %.cxx
$(CXX) $(CXXFLAGS) -o [email protected] $^ $(LDLIBS)
ifneq (,$(findstring r, $(MAKEFLAGS)))
./[email protected]
endif
all: $(SOURCES)
.PHONY: clean
clean:
find . -name "*.out" -delete
Avere che, devi:
- costruire e gestire un file w/
make -r class02
; - build all w/
make
omake all
; - costruire e gestire tutti w/
make -r
(supponiamo che tutti loro contengono qualche certo tipo di cose affermare e si desidera solo per testarli tutti)
export ROOT_DIR=<path/value>
Quindi utilizzare la variabile, $(ROOT_DIR)
nel Makefile .
passare dalla riga di comando con gli spazi fai '' make A = '"come df"' '' –
Sembra che tu stia chiedendo problemi se ti interessano le variabili di ambiente. Per prima cosa, è un incubo di debug se funziona nel posto A e non nel posto B, solo perché hanno ambienti diversi. –
In realtà viene digitato - override dell'ambiente – user7610