Makefile依赖项不适用于虚假目标

Jon*_*gan 17 dependencies makefile

这是我的Makefile的简化版本:

.PHONY: all 

all: src/server.coffee
  mkdir -p bin
  ./node_modules/.bin/coffee -c -o bin src/server.coffee
Run Code Online (Sandbox Code Playgroud)

我想运行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
Run Code Online (Sandbox Code Playgroud)

如果我将Makefile更改为不使用虚假目标,它将按预期工作.新的Makefile:

bin/server.js: src/server.coffee
  mkdir -p bin
  ./node_modules/.bin/coffee -c -o bin src/server.coffee
Run Code Online (Sandbox Code Playgroud)

结果:

$ make
mkdir -p bin
./node_modules/.bin/coffee -c -o bin src/server.coffee
$ make
make: `bin/server.js' is up to date.
Run Code Online (Sandbox Code Playgroud)

为什么它不尊重我对虚假目标的依赖?我问的原因是因为实际上,我不会将单个文件编译成单个其他文件,因此我不想跟踪所有输出文件的名称以用作目标.

小智 13

根据Make文档:

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.
Run Code Online (Sandbox Code Playgroud)

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

Make无条件地运行PHONY目标的配方 - 先决条件无关紧要.


nat*_*evw 12

而不是一个虚假的目标(正如@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
Run Code Online (Sandbox Code Playgroud)

现在你有两件事:一个很好的传统"全部"目标,它是正确的虚假,但不会做额外的工作.您也可以更好地使其更通用,以便您可以轻松添加更多文件:

.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 $<
Run Code Online (Sandbox Code Playgroud)

  • 为了清楚起见,**空目标**必须是一个文件,并且真的只是用于它的时间戳?是否还有其他类型的`.PHONY`允许目标规则具有配方体(带有执行的命令)*和*仅在依赖性需要更新时运行?它看起来很破碎,因为`.PHONY`根据它是否有配方体来做不同的事情. (6认同)

per*_*eal 5

需要有一些目标文件与server.coffee文件的修改时间进行比较.既然你没有具体的目标make就无法知道输出是否更新,那么依赖与否,所以它总是会构建all.