gnu make reloads包含但不更新目标 [英] gnu make reloads includes but doesn't update the targets

查看:90
本文介绍了gnu make reloads包含但不更新目标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个Makefile,该文件将下载并处理文件以生成目标,这是简化版本:

I'm trying to create a Makefile that will download and process file a file to generate targets, this is a simplified version:

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

不幸的是,目标文件在第一次运行时未正确更新,需要再次运行才能获取文件.这是我从中得到的输出:

Unfortunately the target all doesn't get updated properly on the first run, it needs to be run again to get the files. This is the output I get from it:

 $ 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,其文档指出,如果更改了包含的文件,它将重新加载整个内容.怎么了?

I'm using GNU Make 3.81 whose documentation states that it reloads the whole thing if the included files get changed. What is going wrong?

推荐答案

您已将filelist.d指定为.PHONY目标,因此请确保使该目标实际上并未更新指定的文件.但是,确实如此,新内容将在下一次运行中使用.对于第一次运行,丢失的文件不是错误,因为include带有短划线作为前缀.

You have specified filelist.d as a .PHONY target, so make believes making that target doesn't actually update the specified file. However, it does, and the new contents are used on the next run. For the first run, the missing file isn't an error because include is prefixed with the dash.

从.PHONY删除filelist.d.但是,请记住,除非将其删除,否则它不会再次生成(因为它不依赖任何内容).

Remove filelist.d from .PHONY. However, remember it won't be regenerated again until you delete it (as it doesn't depend on anything).

使用相同的令牌,您应在.PHONY中添加默认".

By the same token, you should include "default" in .PHONY.

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

I wrote a shell script rather than lump all this in the 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))

将X替换为在再次下载filelist.d之前可以通过的最大天数:

Replace X with the max number of days that can pass before filelist.d is downloaded again:

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

现在filelist.d取决于.PHONY目标,而本身并不是假冒.这意味着filelist.d总是过时的(语音目标始终是新的"),但是其配方只会定期更新文件.

Now filelist.d depends on a .PHONY target, without being a phony itself. This means filelist.d is always out of date (phony targets are always "new"), but its recipe only updates the file periodically.

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

Unfortunately, this requires you to write the update command as a single command, and space may be a problem if it is long. In that case, I would put it in a separate script as well.

这篇关于gnu make reloads包含但不更新目标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆