Makefile gnu重新加载包括但不包括';不要更新目标

Makefile gnu重新加载包括但不包括';不要更新目标,makefile,gnu-make,Makefile,Gnu Make,我正在尝试创建一个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..." @ech

我正在尝试创建一个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
不幸的是,目标all在第一次运行时没有得到正确更新,需要再次运行以获取文件。这是我从中得到的输出:

 $ 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,它的文档说明,如果包含的文件发生更改,它将重新加载整个过程。出了什么问题?

您已将filelist.d指定为.PHONY目标,因此,创建该目标实际上不会更新指定的文件。但是,确实如此,新内容将在下一次运行时使用。对于第一次运行,缺少的文件不是错误,因为include以破折号作为前缀

从.PHONY中删除文件列表.d。但是,请记住,在删除它之前,它不会再次重新生成(因为它不依赖于任何东西)

同样,您应该在.PHONY中包含“default”


我编写了一个shell脚本,而不是将所有这些都放在makefile中:

#!/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))
现在filelist.d依赖于一个.PHONY目标,而不是一个PHONY本身。这意味着filelist.d总是过时(虚假目标总是“新的”),但它的配方只是定期更新文件


不幸的是,这要求您将update命令作为单个命令编写,如果空间太长,则可能会有问题。在这种情况下,我也会将其放在一个单独的脚本中。

谢谢,不过有一个问题,因为我不知道ftp服务器何时会更新,所以每次运行时我都需要重新创建filelist.d,但至少我知道发生了什么。遗憾的是,你不能在make中指定URL作为依赖项,这样它就可以检查远程url的时间戳。
filelist.d: force-make
        ./less-than-days $@ X || command-to-update
.PHONY: force-make
force-make: