2014-05-16 18 views
9

Ho una configurazione simile a questo:Come passare il nome del target all'elenco dei sotto-makefile?

/Makefile 
/foo/Makefile 
/foo/bar/Makefile 
/foo/baz/Makefile 

Il Makefile di livello superiore contiene un compito che chiama il /foo/Makefile. Questo Makefile crea un elenco di makefile nelle sottodirectory (bar, baz nell'esempio). Per ogni sotto-directory, si chiama i Makefile:

$(SUB_DIRS): 
    $(MAKE) -C [email protected] 

che va bene per, diciamo, il compito all. Ma se voglio fare qualcos'altro, mi blocco. Esiste la possibilità di passare il target all'elenco di sotto-makefile? Per esempio:

$(SUB_DIRS): 
    $(MAKE) -C [email protected] <task> 

clean: $(SUB_DIRS)-clean # or something? 

O è tutta la mia concezione sbagliata?

+0

Ho fatto cose del genere, ma io sono interessato a altre soluzioni a questo problema – UpAndAdam

+0

anche Lei non avrebbe potuto "fare cose come questa", poiché non c'è soluzione. Il mio esempio non funziona affatto. – musicmatze

+0

Quale versione di make stai usando, faccio esattamente questo – UpAndAdam

risposta

7

si può semplicemente utilizzare la variabile $(MAKECMDGOALS).

Make imposterà la variabile speciale MAKECMDGOALS nell'elenco di obiettivi specificato sulla riga di comando. Se non sono stati assegnati obiettivi sulla riga di comando, questa variabile è vuota.

$(SUB_DIRS): 
    $(MAKE) -C [email protected] $(MAKECMDGOALS) 

È inoltre possibile utilizzare la funzione $(foreach) in questo modo:

clean: 
    $(foreach DIR, $(SUB_DIRS), $(MAKE) -C $(DIR) [email protected];) 
+1

Per la cronaca: Questo (quello 'MAKECMDGOALS') è la soluzione più pulita. Anche la mia soluzione funziona. L'approccio 'foreach' funziona, ma se vuoi fare' make -j 4' (per esempio) l'approccio 'foreach' non scala, suppongo. – musicmatze

0

Sì, lo fai semplicemente come specificato, il divertimento arriva nella gestione al livello successivo quando puoi voler fare qualcosa e anche ricrearlo di nuovo.

per esempio ho un'installazione ricorsivo come questo:

$(INSTALL_DIRS): 
    $(MAKE) -C [email protected] install 
+0

Questo non risolve il mio problema. – musicmatze

2

finalmente ho potuto farlo funzionare. L'approccio è:

SUB_DIRS  = $(wildcard */.) 
SUB_DIRS_ALL = $(SUB_DIRS:%=all-%) 
SUB_DIRS_TEST = $(SUB_DIRS:%=test-%) 
SUB_DIRS_CLEAN = $(SUB_DIRS:%=clean-%) 

# 
# Standard task 
# 
all: $(SUB_DIRS_ALL) 

test_uml: $(SUB_DIRS_TEST) 

clean: $(SUB_DIRS_CLEAN) 

$(SUB_DIRS_ALL): 
     @$(MAKE) $(MAKE_FLAGS) -C $(@:all-%=%) 

$(SUB_DIRS_TEST): 
     @$(MAKE) $(MAKE_FLAGS) -C $(@:test-%=%) test 

$(SUB_DIRS_CLEAN): 
     @$(MAKE) $(MAKE_FLAGS) -C $(@:clean-%=%) clean 

ho trovato questa soluzione qui: http://lackof.org/taggart/hacking/make-example/

+1

E questa è fondamentalmente la stessa cosa che ho postato, appena estrapolata ulteriormente per quando non è possibile utilizzare il nome della directory stessa. (è necessario prefisso/suffisso e quindi rimuovere il prefisso/suffisso al momento dell'esecuzione). Faccio spesso quasi esattamente come hai descritto, e non volevo postarlo letteralmente perché speravo che qualcuno potesse presentare qualcosa che non avevo ancora scoperto come MAKECMDGOALS per risolvere veramente il problema, e personalmente non ho visto il valore in oltre ciò che avevo già descritto. – UpAndAdam