create - makefile linux c
gnu make reloads incluye pero no actualiza los objetivos (1)
Intento crear un Makefile que descargue y procese un archivo para generar objetivos, esta es una versión simplificada:
default: all
.PHONY: all clean filelist.d
clean:
@rm -fv *.date *.d
#The actual list comes from a FTP file, but let''s simplify things a bit
filelist.d:
@echo "Getting updated filelist..."
@echo "LIST=$(shell date +/%M)1.date $(shell date +/%M)2.date" > $@
@echo ''all: $$(LIST)'' >> $@
%.date:
touch $@
-include filelist.d
Lamentablemente, el objetivo no se actualiza correctamente en la primera ejecución, necesita ejecutarse nuevamente para obtener los archivos. Este es el resultado que obtengo de él:
$ make
Getting updated filelist...
make: Nothing to be done for `default''.
$ make
Getting updated filelist...
touch 141.date
touch 142.date
touch 143.date
Estoy usando GNU Make 3.81 cuya documentación indica que vuelve a cargar todo si se cambian los archivos incluidos. ¿Qué está pasando mal?
Usted ha especificado filelist.d como un objetivo .PHONY, por lo que cree que hacer ese objetivo en realidad no actualiza el archivo especificado. Sin embargo, sí lo hace, y los nuevos contenidos se usan en la próxima ejecución. Para la primera ejecución, el archivo que falta no es un error porque include tiene el prefijo con el guión.
Elimina filelist.d de .PHONY. Sin embargo, recuerde que no volverá a regenerarse hasta que lo elimine (ya que no depende de nada).
Por la misma razón, debe incluir "predeterminado" en .PHONY.
Escribí un script de shell en lugar de agrupar todo esto en el archivo MAKE:
#!/bin/bash
# Check whether file $1 is less than $2 days old.
[ $# -eq 2 ] || {
echo "Usage: $0 FILE DAYS" >&2
exit 2
}
FILE="$1"
DAYS="$2"
[ -f "$FILE" ] || exit 1 # doesn''t exist or not a file
TODAY=$(date +%s)
TARGET=$(($TODAY - ($DAYS * 24 * 60 * 60)))
MODIFIED=$(date -r "$FILE" +%s)
(($TARGET < $MODIFIED))
Reemplace X con el número máximo de días que pueden transcurrir antes de que filelist.d se descargue nuevamente:
filelist.d: force-make
./less-than-days $@ X || command-to-update
.PHONY: force-make
force-make:
Ahora filelist.d depende de un objetivo .PHONY, sin ser un falso en sí mismo. Esto significa que filelist.d siempre está desactualizado (los destinos falsos son siempre "nuevos"), pero su receta solo actualiza el archivo periódicamente.
Desafortunadamente, esto requiere que escriba el comando de actualización como un solo comando, y el espacio puede ser un problema si es largo. En ese caso, lo pondría en un script separado también.