Pregunta

Asumir un objetivo foo.tar, que depende de una lista de archivos foo.files, p.ej

FOO_FILES := $(shell cat foo.files)

foo.tar: foo.files $(FOO_FILES)
    tar -cf foo $(FOO_FILES)

Ahora suponga que los archivos de Foo deben generarse, por ejemplo:

foo.files: foo.files.template
    sed -e "s/@{VERSION}/$(VERSION)/" < $< > $@

Está claro que foo.files depende de foo.files.template, pero ¿cómo se puede asegurar que se evalúe foo_files? después foo.files se genera?

¿Fue útil?

Solución

Sus reglas originales son correctas. Debido a que la actualización de foo.files hace que el valor de foo_files se observe, solo necesita asegurarse de que su makefile sea reevaluado por GNU, cuando Foo.files se ha actualizado haciendo que su makefile dependa de foo.files:

Makefile : foo.files

Otros consejos

Entonces, encontré una respuesta leyendo sobre Generación avanzada de auto dependencia sobre Mad-scientist.net. Básicamente, es posible reevaluar un archivo de make a través de una función GNU/Make. Cuando hay una regla para generar un MakFile incluido, todo el File Makefile se volverá a leer después de la generación del archivo incluido. De este modo --

# -*- mode: make -*-
VERSION := 1.2.3

foo.tar: foo.files $(FOO_FILES)
    tar cf $@ $(FOO_FILES)

clean:
    rm -f foo.files foo_files.mk foo.tar

foo.files: foo.files.template
    sed -e "s/@{VERSION}/$(VERSION)/" < $< > $@

# -- voodoo start here --
# This will ensure that FOO_FILES will be evaluated only
# *after* foo.files is generated.
foo_files.mk: foo.files
    echo "FOO_FILES := `xargs < $<`" > $@

include foo_files.mk
# -- voodoo ends here --

.PHONY: clean

- parece hacer lo correcto.


... y solo por integridad:

foo.files.template es:

a-$(VERSION)
b-$(VERSION)

y asumir la presencia de a-1.2.3 y b-1.2.3.

No se puede hacer en un solo pase; Hacer determinar qué objetivos deben reconstruirse antes de que realmente ejecute cualquier regla, y en este caso la lista completa de objetivos no existe hasta que se ejecute una de las reglas.

Esto debería hacerlo:

FOO_FILES := $(shell cat foo.files)

foo.tar: foo.files
    $(MAKE) foo-tarball

.PHONY: foo-tarball
foo-tarball: $(FOO_FILES)
    tar -cf foo $^

EDITAR:
Como señala el OP, esto no funcionará como está escrito; Dejé un requisito previo:

foo.tar: foo.files $(FOO_FILES)
    ...

Tenga en cuenta que esto se recurrirá incluso si foo.files no ha cambiado, lo que no es estrictamente necesario; Es posible corregir esto, pero no elegantemente. (Para comparación, la solución seleccionada, que admito que es más limpia que la mía, se repite incluso si el objetivo no tiene nada que ver con foo.tar.)

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