9

rm filenameGNU make 通过在末尾调用自动删除由隐式规则创建的中间文件。如果其中一个目标实际上是一个目录,这显然不起作用。举个例子:

.PHONY: all 

all: test.target

%.target: tempdir.% 
  touch $@

tempdir.%:
  mkdir -p $@

make -n揭示行动计划:

mkdir -p tempdir.test
touch test.target
rm tempdir.test

是否可以让 GNU make 正确处理中间目录?也许通过更改rmrm -rf?

4

1 回答 1

7

没有办法做到这一点。尽管 GNU make 打印命令“rm”,但实际上它在内部直接运行 unlink(2) 系统调用,而不是调用 shell 命令。无法配置或修改 GNU make 运行的命令(当然,除非更改源代码)。

但是,我觉得我应该指出,将目录用作目标的正常先决条件是行不通的。GNU make 使用 time-last-modified 比较来判断目标何时是最新的,并且目录的 time-last-modified 不遵循标准规则。每次创建、删除或重命名目录中的文件(或子目录)时,都会更新目录的 TLM 。这意味着您将创建目录,然后有一堆依赖于它的文件:第一个已构建并具有时间戳 N。最后一个已构建并具有时间戳 N+x。这也将目录的时间戳设置为 N+x。然后下次运行 make 时,它​​会注意到第一个时间戳 (N) 比它的一个先决条件(目录,在 N+x)更旧,然后重新构建。

这将永远发生,直到它可以足够快地构建剩余的“过时”先决条件,以至于它们的时间戳不比目录新。

而且,如果您要在该目录中删除临时文件或编辑器备份文件或其他内容,它将重新开始。

只是不要这样做。

有些人使用显式的 shell 命令来创建目录。有些人将它们创建为目标创建的副作用。有些人使用仅限订单的先决条件来确保按时创建它们。

于 2013-03-01T12:33:52.350 回答