Makefile的依赖没有为假目标工作(Makefile dependencies don'

2019-07-05 03:11发布

这里是我的Makefile的简化版本:

.PHONY: all 

all: src/server.coffee
  mkdir -p bin
  ./node_modules/.bin/coffee -c -o bin src/server.coffee

我想运行make ,只有把它重新编译时src/server.coffee发生了变化。 然而,重新编译每次运行时make

$ make
mkdir -p bin
./node_modules/.bin/coffee -c -o bin src/server.coffee
$ make
mkdir -p bin
./node_modules/.bin/coffee -c -o bin src/server.coffee

如果我改变我的Makefile中不使用假目标,它按预期工作。 新的Makefile:

bin/server.js: src/server.coffee
  mkdir -p bin
  ./node_modules/.bin/coffee -c -o bin src/server.coffee

结果:

$ make
mkdir -p bin
./node_modules/.bin/coffee -c -o bin src/server.coffee
$ make
make: `bin/server.js' is up to date.

为什么不是我的尊重与依赖假冒的目标是什么? 我想问的原因是因为在现实中,我将不只是编译一个单一的文件到一个单一的其他的文件,所以我不希望有跟踪所有输出文件的名称作为目标来使用。

Answer 1:

而不是假目标(这是@cmotley指出,正在努力正是因为它应该),你可能会使用什么,当你想避免额外的工作是一个“空靶” :

空目标是假目标的变体; 它是用来保存的食谱,你明确要求,不时的动作。 不像假目标,这个目标文件可以真实存在; 但文件的内容并不重要,通常是空的。

空目标文件的目的是记录,其最后修改时间,最后执行的规则的配方时。 它这样做是因为在配方中的命令之一是触摸命令更新目标文件。

然而 ,在这种情况下,实在没有必要添加额外的空输出文件-你已经有你的CoffeeScript编译输出! 适合比较典型的Makefile模式,因为你已经在你的问题证明。 你可以做的就是重构这个方法:

.PHONY: all
all: bin/server.js

bin/server.js: src/server.coffee
  mkdir -p bin
  ./node_modules/.bin/coffee -c -o bin src/server.coffee

现在你有两件事情:一个很好的传统的“所有”目标是正确的假,但不会做额外的工作。 你也是一个更好的位置,以使这更通用的,因此您可以轻松地添加更多的文件:

.PHONY: all
all: bin/server.js bin/other1.js bin/other2.js

bin/%.js: src/%.coffee
  mkdir -p bin
  ./node_modules/.bin/coffee -c -o bin $<


Answer 2:

按照制作文档:

The prerequisites of the special target .PHONY are considered
to be phony targets. When it is time to consider such a target, 
make will run its recipe unconditionally, regardless of whether 
a file with that name exists or what its last-modification time is.

http://www.gnu.org/software/make/manual/html_node/Special-Targets.html

使运行的无条件假目标的食谱 - 先决条件没有关系。



Answer 3:

需要有一些目标文件进行比较的server.coffee文件的修改时间。 既然你没有一个具体的目标make也无法知道,如果输出是新的,则依赖或没有,所以它总是建立all



Answer 4:

正如其他人所说,使着眼于文件的时间戳弄清楚,如果依赖已经改变。

如果你想“模仿”与依赖假目标,你必须创建具有该名称的实际文件,并使用touch命令(在UNIX系统)。

我需要一个解决方案,只清理目录,如果生成文件被改变(即编译器标志发生了变化,所以需要的目标文件进行重新编译)。

下面是我用什么(编译每次运行前)与一个文件名为makefile_clean

makefile_clean: makefile
    @rm '*.o'
    @sudo touch makefile_clean

touch命令更新上次修改的时间戳到当前的时间。



文章来源: Makefile dependencies don't work for phony target