GNU Make Reloads включает, но не обновляет цели - PullRequest
1 голос
/ 27 сентября 2010

Я пытаюсь создать Makefile, который будет загружать и обрабатывать файл для генерации целей, это упрощенная версия:

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

К сожалению, цель все не обновляется должным образом при первом запуске, ее нужно запустить снова, чтобы получить файлы. Это вывод, который я получаю от него:

 $ make
Getting updated filelist...
make: Nothing to be done for `default'.
 $ make
Getting updated filelist...
touch 141.date
touch 142.date
touch 143.date

Я использую GNU Make 3.81, в документации которой говорится, что он полностью перезагружается, если изменяются включенные файлы Что не так?

1 Ответ

2 голосов
/ 27 сентября 2010

Вы указали filelist.d в качестве цели .PHONY, поэтому убедитесь, что создание этой цели на самом деле не обновляет указанный файл. Однако это так, и новое содержимое используется при следующем запуске. При первом запуске отсутствующий файл не является ошибкой, потому что в качестве префикса include используется тире.

Удалить filelist.d из .PHONY. Однако помните, что он не будет восстановлен снова, пока вы не удалите его (так как это ни от чего не зависит).

К тому же токену, вы должны включить «default» в .PHONY.


Я написал сценарий оболочки вместо того, чтобы объединить все это в 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))

Замените X на максимальное количество дней, которое может пройти до повторной загрузки filelist.d:

filelist.d: force-make
        ./less-than-days $@ X || command-to-update
.PHONY: force-make
force-make:

Теперь filelist.d зависит от цели .PHONY, но не является фальшивкой. Это означает, что filelist.d всегда устарел (фальшивые цели всегда «новые»), но его рецепт только периодически обновляет файл.

К сожалению, для этого необходимо написать команду обновления как одну команду, и пробел может стать проблемой, если он длинный. В этом случае я бы поставил его и в отдельный скрипт.

...