即使底层文件没有改变,make 也会运行命令

make runs command even if underlying files have not changed

如果 Unix/ 目录中的任何文件发生更改,我想重新编译 Unix.zwc。我创建了这个 Makefile:

all:    Unix.zwc
    zsh -c 'zcompile -Uz Unix.zwc Unix/*'

Unix.zwc:   Unix/*

但是当我 运行 make 时,它总是重新编译文件 Unix.zwc,即使文件 Unix/* 中的 none 已更改。

我做错了什么?

通过比较文件的时间戳来制作作品。这条规则:

all:    Unix.zwc

表示 all 文件将被更新,如果 (a) 它不存在或 (b) 它存在但它的最后修改时间早于文件 Unix.zwc

也许您现在可以明白为什么总是重建所有内容:文件 all 从来不存在,因此它总是被认为是过时的,所以配方总是 运行。我不知道 zcompile 命令实际上做了什么,但是这个目标的名称不应该是 all 它应该是 zcompile 命令生成的任何文件,否则你会例如,必须使用 touch $@ 手动创建 all 目标。

其次,此规则不符合您的预期:

Unix.zwc:   Unix/*

你这里没有配方,这意味着make永远不会更新Unix.zwc,这意味着当Unix中的文件时all不会过时变化。如果 all 目标同时依赖 Unix.zwc 文件 Unix 目录中的文件(看起来确实如此),那么您应该删除上面的先决条件声明并将all写为:

all:    Unix.zwc Unix/*
        zsh -c 'zcompile -Uz Unix.zwc Unix/*'
        touch $@

What am I doing wrong?

您正在将编译 Unix.zwc 的命令放入(虚假)目标 all 的配方中,而不是其自身目标的配方中。

因为all不存在,它的配方总是运行。对于 GNU make,建议更进一步,明确声明它是假的,以确保配方是 运行,即使实际上创建了一个名为 all 的文件。

你要的是这个:

all:    Unix.zwc

Unix.zwc:   Unix/*
    zsh -c 'zcompile -Uz Unix.zwc Unix/*'

.PHONY: all