Is an empty target rule a viable substitute for .DEFAULT_GOAL in GNU Make

gnumakefile

GNU Make version 3.81 introduced a special variable named .DEFAULT_GOAL that can be used to tell Make which goal (or target) should be built if no target was specified on the command line. Otherwise Make will simply make the first target it encounters.

Consider:

bar: a b c
        ${MAKE_BAR_COMMANDS}

foo: x y z
        ${MAKE_FOO_COMMANDS}

With the above hypothetical Makefile, running make will build "bar", because it is the first target that Make encounters. But if we add .DEFAULT_GOAL, like so …

.DEFAULT_GOAL := foo    # Build foo by default, even if it's not first.

bar: a b c
        ${MAKE_BAR_COMMANDS}

foo: x y z
        ${MAKE_FOO_COMMANDS}

… then Make (version 3.81) will build "foo" if we run just make.

I've found this .DEFAULT_GOAL variable to be quite useful in a modular, re-usable Makefile "framework" that I've built. However, I'm finding that many systems still have GNU Make 3.80 or older and they don't support this variable.

While playing around with things, I noticed that simply specifying an empty target rule seems to have the same effect as .DEFAULT_GOAL, even on pre-3.81 versions of GNU Make:

foo:    # Empty target rule

bar: a b c
        ${MAKE_BAR_COMMANDS}

foo: x y z
        ${MAKE_FOO_COMMANDS}

I know that it is valid and legal to add to a target's rules and/or prerequesites by specifying additional target rules in this manner. However, I'm wondering if doing this might introduce some potentially undesirable side-effects that do not occur when using .DEFAULT_GOAL.

I guess I'm left wondering why .DEFAULT_GOAL was introduced if you can achieve the same thing with a simple empty target rule. This makes me suspect that they maybe don't result in exactly the same behavior.

So the bottom line questions is: is there an externally detectable difference between using .DEFAULT_GOAL versus an empty target rule?

Best Answer

I can't give you a definite answer, but I can suggest other reasons for its introduction:

  1. It's immediately obvious what .DEFAULT_GOAL does; i.e. what it says on the label. The presence and meaning of a single-line empty target is easily glossed over, especially in a larger Makefile
  2. You can actually read the value of $(.DEFAULT_GOAL) back elsewhere in the Makefile. Testing suggests it makes no difference whether it's explicitly set, or whether it's determined by picking the first rule.