Makefile dependencies don’t work for phony target

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.

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

Leave a Comment