Passando ulteriori variabili dalla riga di comando per rendere

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.

Hai diverse opzioni per impostare le variabili al di fuori del tuo makefile:

  • Dall’ambiente : ogni variabile d’ambiente viene trasformata in una variabile makefile con lo stesso nome e valore.

    Potresti anche voler impostare l’opzione -e (alias --environments-override ) e le variabili di ambiente sovrascriveranno i compiti creati nel makefile (a meno che questi stessi incarichi non utilizzino la direttiva override .) Tuttavia, non è raccomandato, ed è molto meglio e flessibile da usare ?= assegnazione (l’operatore di assegnazione della variabile condizionale, ha solo un effetto se la variabile non è ancora definita):

     FOO?=default_value_if_not_set_in_environment 

    Nota che alcune variabili non sono ereditate dall’ambiente:

    • MAKE è ottenuto dal nome dello script
    • SHELL è impostato all’interno di un makefile o predefinito su /bin/sh (rationale: i comandi sono specificati all’interno del makefile e sono specifici della shell).
  • Dalla riga di comandomake può assumere assegnazioni variabili come parte della sua linea di comando, mescolate con gli obiettivi:

     make target FOO=bar 

    Ma poi tutti i compiti assegnati alla variabile FOO all’interno del makefile verranno ignorati a meno che non si utilizzi la direttiva override nell’assegnazione. (L’effetto è lo stesso di con l’opzione -e per le variabili di ambiente).

  • Esportare dal Make genitore – se chiami Make da un Makefile, di solito non dovresti scrivere esplicitamente assegnazioni di variabili come questa:

     # Don't do this! target: $(MAKE) -C target CC=$(CC) CFLAGS=$(CFLAGS) 

    Invece, una 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 ansible esportare tutte le variabili utilizzando l’ export senza argomenti.

Il modo più semplice è:

 make foo=bar target 

Quindi nel tuo makefile puoi fare riferimento a $(foo) . Nota che questo non si propagherà automaticamente alle sub-marche.

Se si utilizzano sottostrutture, vedere questo articolo: Comunicazione di variabili a una sottostringa

Supponi di avere un makefile come questo:

 action: echo argument is $(argument) 

Dovresti quindi chiamarlo make action argument=something

Dal manuale :

Le variabili nella marca possono provenire dall’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.

Quindi puoi fare (da bash):

 FOOBAR=1 make 

risultante in una variabile FOOBAR nel tuo Makefile.

Se crei un file chiamato Makefile e aggiungi una variabile come $ (unittest), allora sarai in grado di usare questa variabile all’interno del Makefile anche con i caratteri jolly

esempio :

 make unittest=* 

Io uso BOOST_TEST e assegnando un carattere jolly al parametro –run_test = $ (unittest), quindi userò l’espressione regolare per filtrare il test che voglio che il mio Makefile esegua

 export ROOT_DIR= 

Quindi utilizzare la variabile $(ROOT_DIR) nel Makefile.

C’è un’altra opzione non citata qui che è inclusa nel libro GNU Make di Stallman e McGrath (vedi http://www.chemie.fu-berlin.de/chemnet/use/info/make/make_7.html ). Fornisce l’esempio:

 archive.a: ... ifneq (,$(findstring t,$(MAKEFLAGS))) +touch archive.a +ranlib -t archive.a else ranlib archive.a endif 

Si tratta di verificare se un determinato 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 tutti ed eseguire individualmente o compilare uno alla volta ed eseguirlo se viene specificato un flag ( -r , ad esempio). Quindi, potresti trovare 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 

Avendo ciò, tu:

  • costruisci ed esegui un file con make -r class02 ;
  • costruisci tutto w / make o make all ;
  • costruisci ed esegui tutto w / make -r (supponiamo che tutti contengano un certo tipo di cose assert e tu voglia solo testarli tutti)