Pregunta

Tengo que integrar la generación de muchos archivos HTML en un Makefile existente. El problema es que los archivos HTML tienen que residir en muchos directorios diferentes. Mi idea es escribir una regla implícita que convierte el archivo de origen (* .st) al archivo html correspondiente

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

y una regla que depende de todos los archivos html

all: $(html)

Si el archivo HTML no está en la make builddir no encontrar la regla implícita: *** No rule to make target. Si cambio la regla implícita al igual que

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

Se encuentra, pero entonces tiene que tener una regla implícita para prácticamente todos los archivos en el proyecto. De acuerdo con implícito Regla algoritmo de búsqueda en el GNU manual de make, de búsqueda de reglas funciona así:

  
      
  1. Split t en una parte del directorio, llamado D, y el resto, llamada n. por   ejemplo, si t es src/foo.o', then d issrc / 'y n es `foo.o'.
  2.   
  3. Haga una lista de todo el patrón gobierna uno de cuyos objetivos partidos t o n.   Si el patrón de destino contiene una   raya vertical, que se compara con t;   de otro modo, en contra de n.
  4.   

¿Por qué no se encuentra la regla implícita, y cuál sería la solución más elegante, suponiendo que se utiliza make GNU?

Esta es una versión simplificada de mi 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)
¿Fue útil?

Solución

Al igual que María Shalnova me gusta hacer recursiva (aunque no estoy de acuerdo con "Make recursiva Considerado nocivas"), y, en general, es mejor hacer algo aquí de una fuente de NO, no a la inversa. Pero si debe hacerlo, puedo sugerir una ligera mejora: tener generateHtml generar solamente la regla, no los comandos

.

Otros consejos

La mejor solución que encontré hasta ahora es generar una regla implícita por directorio de destino a través de foreach-eval-llaman , como se explica en el GNU make manual de . No tengo idea de cómo esta escala a unos pocos miles de directorios de destino, pero vamos a ver ...

Si usted tiene una mejor solución, por favor, publicarlo!

Este es el código:

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)

Su regla implícita activo hace $(rootdir)/build/doc/2009/06/01/some.html dependen de $(rootdir)/build/doc/2009/06/01/some.st. Si $(rootdir)/build/doc/2009/06/01/some.st no existe, entonces no va a utilizar la regla / encontrado.

La regla comentada hace $(rootdir)/build/doc/2009/06/01/some.html dependen de some.st.

Una solución es hacer que estés diseño fuente coincide con su / layout resultado destino.

Otra opción es crear las reglas según sea necesario con eval . Pero eso va a ser bastante complicado:

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

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

Otra posibilidad es que el comando make llamarse a sí mismo de forma recursiva con el argumento -C con cada directorio de salida. make recursivo es un poco la forma estándar para hacer frente a los subdirectorios, pero cuidado con las consecuencias mencionadas en el artículo "Hacer recursiva Considerado nocivas"

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top