Vineel
Vineel

Reputation: 1440

Make command using default target name 'Makefile'

Why is the following makefile using Makefile target?

Makefile1: Initially I have the following makefile which worked as expected when invoked as make abc xyz -s.

%::
echo $@

I would get

abc
xyz

Makefile2: Now after adding an empty rule named test.

%:: test
     echo $@
test:

the following invocation

make abc xyz -s

results in

Makefile
abc
xyz

Why am I getting Makefile as my output even though I am giving only abc and xyz as targets? Thanks in advance.

Upvotes: 2

Views: 380

Answers (1)

Jan Hudec
Jan Hudec

Reputation: 76306

Because make always tries to rebuild the build files before building the actual targets. If it finds a rule for Makefile and if it is out-of-date, it will be rebuilt and reloaded and the requested targets will be built according to the new makefile. This is a feature so that if the build-files are themselves generated (rather common with autotools, cmake and similar), it won't use stale build instructions.

For more details see GNU Make Manual section 3.5

In the specific examples above the rule has target % and that matches absolutely anything, including Makefile. So make will find it as rule for remaking makefile and will evaluate it.

Now in the first case Makefile exists and is newer than all of it's dependencies trivially because there are none and none of it's dependencies need to be remade also because there are none. So make will conclude that Makefile does not need to be remade.

In the second case however Makefile exists, but it's dependency test needs to be remade. So make runs the (empty) rule and than comes back and runs the rule for Makefile. Because make does not check the timestamps after making dependencies. It simply assumes that when it remade them, the dependent targets need to be remade as well.

Upvotes: 5

Related Questions