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

查看:27
本文介绍了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.

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

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.

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

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天全站免登陆