Makefile依赖项不适用于伪造目标 [英] Makefile dependencies don't work for phony target

查看:91
本文介绍了Makefile依赖项不适用于伪造目标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的Makefile的简化版本:

Here is a reduced version of my 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时,它都会重新编译:

I want to run make and only have it recompile when src/server.coffee has changed. However, it recompiles every time I run 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:

If I change my Makefile to not use a phony target, it works as expected. New 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.

为什么它不以假冒的目标尊重我的依附关系?我问的原因是因为实际上,我不会只是将一个文件编译成另一个文件,所以我不想跟踪要用作目标的所有输出文件的名称. /p>

Why won't it respect my dependencies with a phony target? The reason I ask is because in reality, I won't just be compiling a single file into a single other file, so I don't want to have to keep track of the names of all the output files to use as targets.

推荐答案

而不是一个伪造的目标(正如@cmotley指出的那样,它的工作完全正常),当您要避免进行额外的工作时,可以使用的是空目标" :

Rather than a phony target (which as @cmotley points out, is working exactly as it should) what you might use when you want to avoid extra work is an "empty target":

空目标是伪目标的变体;它用于保存您不时明确请求的操作的配方.与伪造目标不同,该目标文件可以真正存在.但是文件的内容并不重要,通常为空.

The empty target is a variant of the phony target; it is used to hold recipes for an action that you request explicitly from time to time. Unlike a phony target, this target file can really exist; but the file's contents do not matter, and usually are empty.

空目标文件的目的是记录上一次执行规则的配方及其最后修改时间.这样做是因为配方中的命令之一是用于更新目标文件的touch命令.

The purpose of the empty target file is to record, with its last-modification time, when the rule's recipe was last executed. It does so because one of the commands in the recipe is a touch command to update the target file.

但是,在这种情况下,实际上不需要添加额外的空输出文件-您已经拥有CoffeeScript编译的输出!正如您在问题中已经演示的那样,这适合更典型的Makefile模式.您可以做的就是重构这种方法:

However, in this case there's really no need to add an extra empty output file — you already have the output of your CoffeeScript compilation! That fits the more typical Makefile pattern, as you already demonstrated in your question. What you could do is refactor to this approach:

.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

现在,您同时拥有两个想要的东西:一个很好的常规全部"目标,可以正确地伪造,以及一个构建规则,不会做额外的工作.您也可以使其更通用,从而可以轻松添加更多文件:

Now you have both things you wanted: a nice conventional "all" target that is correctly phony, and a build rule that won't do extra work. You are also in a better position to make this more generic so you can easily add more files:

.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 $<

这篇关于Makefile依赖项不适用于伪造目标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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