Domanda

devo integrare la generazione di molti file HTML in un Makefile esistente. Il problema è che i file HTML devono risiedere in molte directory differenti. La mia idea è quella di scrivere una regola implicita che converte il file sorgente (* .st) per il file HTML corrispondente

%.html: %.st
    $(HPC) -o $@ $<

e una regola che dipende da tutti i file HTML

all: $(html)

Se il file HTML non è nella make builddir non trova la regola implicita: *** No rule to make target. Se cambio la regola implicita in questo modo

$(rootdir)/build/doc/2009/06/01/%.html: %.st  
    $(HPC) -o $@ $<

è trovato, ma poi devo avere una regola implicita per quasi tutti i file nel progetto. Secondo implicita regola algoritmo di ricerca nel manuale make GNU, regola di ricerca funziona in questo modo:

  
      
  1. Spalato t in una parte directory, chiamato d, e il resto, chiamato n. Per   esempio, se t è src/foo.o', then d issrc / 'e n è `foo.o'.
  2.   
  3. Fare un elenco di tutto il modello di regole di cui uno degli obiettivi partite t o n.   Se il modello di destinazione contiene un   slash viene confrontato t;   in caso contrario, contro n.
  4.   

Perché la regola implicita non trovato, e quale sarebbe la soluzione più elegante, assumendo GNU make viene utilizzato?

Ecco una versione ridotta del mio Makefile:

rootdir  = /home/user/project/doc
HPC      = /usr/local/bin/hpc

html = $(rootdir)/build/doc/2009/06/01/some.html

%.html: %.st
    $(HPC) -o $@ $<

#This works, but requires a rule for every output dir
#$(rootdir)/build/doc/2009/06/01/%.html: %.st  
#   $(HPC) -o $@ $<

.PHONY: all
all: $(html)
È stato utile?

Soluzione

Come Maria Shalnova mi piace ricorsiva make (anche se non sono d'accordo con "Make ricorsiva considerati nocivi"), e in generale è meglio fare qualcosa qui da una fonte lì, non il contrario. Ma se è necessario, mi permetto di suggerire un leggero miglioramento: avere generateHtml generare solo la regola, non l'COMANDI

.

Altri suggerimenti

La soluzione migliore che ho trovato finora è quello di generare una regola implicita per directory di destinazione tramite foreach-eval-CALL , come spiegato nel GNU make manuale . Non ho idea di come questo di scalare fino a qualche migliaio di directory di destinazione, ma vedremo ...

Se si dispone di una soluzione migliore, si prega di postare!

Ecco il codice:

rootdir  = /home/user/project/doc
HPC      = /usr/local/bin/hpc

html = $(rootdir)/build/doc/2009/06/01/some.html \
       $(rootdir)/build/doc/2009/06/02/some.html

targetdirs = $(rootdir)/build/doc/2009/06/01 \
             $(rootdir)/build/doc/2009/06/02

define generateHtml
 $(1)/%.html: %.st
    -mkdir -p $(1)
    $(HPC) -o $$@ $$<
endef   

$(foreach targetdir, $(targetdirs), $(eval $(call generateHtml, $(targetdir))))

.PHONY: all
all: $(html)

La regola implicita attiva rende $(rootdir)/build/doc/2009/06/01/some.html dipendono $(rootdir)/build/doc/2009/06/01/some.st. Se $(rootdir)/build/doc/2009/06/01/some.st non esiste, allora non sarà utilizzato la regola / trovato.

La regola commentata fa $(rootdir)/build/doc/2009/06/01/some.html dipendono some.st.

Una soluzione è quella di fare sei layout di origine corrisponde la tua destinazione / layout di conseguenza.

Un'altra opzione è quella di creare le regole, come richiesto con eval . Ma che sarà piuttosto complicato:

define HTML_template
 $(1) : $(basename $(1))
      cp $< $@
endef

$(foreach htmlfile,$(html),$(eval $(call HTML_template,$(htmlfile))))

Un altra possibilità è quella di avere il comando make chiamarsi in modo ricorsivo con l'-C argomento con ogni directory di output. make ricorsiva è un po 'il modo standard di trattare con le sottodirectory, ma attenzione le implicazioni di cui l'articolo "Make ricorsivo considerati nocivi"

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top