2011-05-18 17 views
7

Ho diversi widget identificati da uno config.xml nel loro root in a directory layout.Individuazione delle dipendenze di makefile

Il file GNUmake che ho qui è in grado di costruirli. Anche se aggiorno le cartelle, le dipendenze non sono tracciate. Ovviamente non voglio dipendere da un target pulito, quindi come faccio a tenere traccia dei contenuti di ciascuna cartella?

WGTS := $(shell find -name 'config.xml' | while read wgtdir; do echo `dirname $$wgtdir`.wgt; done) 
all: $(WGTS) 
%.wgt: 
    @cd $* && zip -q -r ../$(shell basename $*).wgt . 
    @echo Created [email protected] 
clean: 
    rm -f $(WGTS) 

speravo qualcosa di simile:

%.wgt: $(shell find $* -type f) 

avrebbe funzionato, ma non è così. Help.

+0

Quindi ... volete 'foo.wgt' per dipendere da tutto in' foo/'? – Beta

+0

Proprio così ... – hendry

risposta

4

Combinando Beta's idea con la mia:

 
WGTS := $(shell find -name config.xml) 
WGTS := $(WGTS:/config.xml=.wgt) 
WGTS_d := $(WGTS:.wgt=.wgt.d) 

all: $(WGTS) 
clean: 
    rm -f $(WGTS) $(WGTS_d) 

-include $(WGTS_d) 

define WGT_RULE 
$(1): $(shell find $(1:.wgt=)) 
$(1:.wgt=)/%: 
    @ 
endef 
$(foreach targ,$(WGTS),$(eval $(call WGT_RULE,$(targ)))) 
%.wgt: 
    @echo Creating [email protected] 
    @(echo -n "[email protected]: "; find $* -type f | tr '\n' ' ') > [email protected] 
    @cd $* && zip -q -r ../$(shell basename $*).wgt . 

Esempio:

 
$ mkdir -p foo bar/nested 
$ touch {foo,bar/nested}/config.xml 
$ make 
Creating bar/nested.wgt 
Creating foo.wgt 
$ make 
make: Nothing to be done for `all'. 
$ touch foo/a 
$ make 
Creating foo.wgt 
$ rm foo/a 
$ make 
Creating foo.wgt 
$ make 
make: Nothing to be done for `all'. 

L'unico potenziale problema qui è la regola fittizio che permette di far ignorare obiettivi che non sa come costruire che sono annidati all'interno delle directory. (foo/a nel mio esempio.) Se questi sono obiettivi reali che richiedono di sapere come costruire, la definizione della ricetta duplicata potrebbe essere un problema.

+0

Mi serve per rendere conto dei nuovi file aggiunti. non capisco bene la necessità di scrivere quella cosa .wgt.d, mi sembra crudele. Non ci sarà un caso con config.xml all'interno di un config.xml. :) – hendry

+0

@hendry: Scrivere i file delle dipendenze consente di includerli semplicemente nelle esecuzioni successive senza dover rigenerare tutte queste informazioni. Funziona bene per la maggior parte dei casi (ed è comunemente usato per generare dipendenze C-source sulle intestazioni); ma semplicemente non può gestire l'aggiunta di file con destinazioni che dipendono solo dallo stato del filesystem. –

+0

@thomas Questo Makefile può tenere conto dell'aggiunta e della rimozione dei file, tuttavia non posso adattarlo per tenere conto della struttura di directory arbitraria che i miei widget sono in http://tests.wacapps.net/?p=wac2tests;a= blob; f = campioni/Makefile; Penso che se abbiamo capito http://www.gnu.org/s/hello/manual/make/Secondary-Expansion.html avremmo trovato la risposta – hendry

1

Probabilmente il modo migliore per farlo è quello di creare le liste dei prerequisiti in modo esplicito, a priori: il

define WGT_RULE 
$(1).wgt: $(wildcard $(1)/*) 
endef 

$(foreach targ,$(WGTS),$(eval $(call WGT_RULE,$(targ)))) 

C'è un altro modo che è molto intelligente (una frase che fa un buon programmatore diffidente). Anni fa mi venne in mente un kludge per mancini per trattare una directory come prerequisito. Vedrò se riesco a recuperare i miei vecchi taccuini se quanto sopra non è abbastanza buono.

EDIT:
Spiacente, non ho considerato le sottodirectory. Ecco un makefile completo (ho omesso la regola clean) che dovrebbe fare il trucco.

WGTS := $(shell find -name 'config.xml' | while read wgtdir; do echo `dirname $\ 
$wgtdir`.wgt; done) 
all: $(WGTS) 

# This constructs a rule without commands ("foo.wgt: foo/bar.txt foo/baz.dat..."). 
define WGT_RULE 
$(1).wgt: $(shell find $(1)) 
endef 

# This invokes the above to create a rule for each widget. 
$(foreach targ,$(WGTS),$(eval $(call WGT_RULE,$(targ)))) 

%.wgt: 
    @cd $* && zip -q -r ../$(shell basename $*).wgt . 
    @echo Created [email protected] 
+0

Ho appena provato a creare un nuovo file in una sottodirectory e il makefile non lo ha raccolto. :(Esiste un modo per evitare questo WGT_RUL? Sembra un po 'inutile per me. Preferirei a destra di% .wgt: 'Mi dispiace essere difficile ... – hendry

+0

Questo non funziona:' hendry @ x201 foo $ bar mkdir Hendry @ x201 foo $ touch bar/config.xml Hendry @ x201 foo $ make ritrovamento: './bar.wgt ': Nessun file o directory Creato bar.wgt Hendry @ x201 foo $ make marca: Niente da fare per 'tutti ' Hendry @ x201 foo $ vim Makefile Hendry @ x201 foo $ touch bar/foo Hendry @ x201 foo $ make marca:. Niente da fare per' tutti'. hendry @ x201 foo $ ' – hendry

Problemi correlati