help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Build target everytime when make


From: Paul Smith
Subject: Re: Build target everytime when make
Date: Mon, 08 Aug 2011 08:26:54 -0400

On Mon, 2011-08-08 at 11:35 +0800, Dannoy Lee wrote:
>    In the following Makefile,I want make a.c rebuild everytime I type make
> command by using FORCE as a prerequisite of a.c

> -include a.d
> 
> a.c:FORCE
>         touch $@
> %.d:%.c
>         echo $*.o $*.d : $*.c > $*.d
> 
> FORCE:
> .PHONY:FORCE
> 
> But it will ouputs
> 
> touch a.c
> echo a.o a.d : a.c > a.d
> touch a.c
> echo a.o a.d : a.c > a.d
> 
> And It cannot stop.

Yes.  When a file included by make (in this case "a.d") is rebuilt by
make, then make will re-exec itself to re-read the new makefile.  The
new version of make will again try to rebuild its included files ("a.d")
and if it is rebuilt, it will again re-exec itself.  And on and on.

If you declare a prerequisite of an included file to be phony or force
it to always be rebuilt, then make will always rebuild the included file
("a.d") and re-exec itself, forever.

> So I change the previous Makefile as follows:
> all:a.d a.o
>         touch $@
> 
> -include a.d
> 
> a.c:
>         touch $@
> %.d:%.c
>         echo $*.o $*.d : $*.c > $*.d
> 
> %.o:%.c
>         touch $@
> 
> .INTERMEDIATE:a.c
> 
> FORCE:
> .PHONY:FORCE
> When I run make the first time,it outputs:
> touch a.c
> echo a.o a.d : a.c > a.d
> rm a.c
> touch a.c
> touch a.o
> touch all
> rm a.c
> When I run make again,it outputs:
> make: `all' is up to date.
> So I run it with -d,and I noticed the following ouput:
> Updating goal targets....
> Considering target file `all'.
>   Pruning file `a.d'.
>   Considering target file `a.o'.
>    Looking for an implicit rule for `a.o'.
>    Trying pattern rule with stem `a'.
>    Trying implicit prerequisite `a.c'.
>    Found an implicit rule for `a.o'.
>    Finished prerequisites of target file `a.o'.
>    Prerequisite `a.c' of target `a.o' does not exist.
>    Prerequisite `a.c' of target `a.o' does not exist.
>   No need to remake target `a.o'.
>  Finished prerequisites of target file `all'.
>  Prerequisite `a.d' is older than target `all'.
>  Prerequisite `a.o' is older than target `all'.
> No need to remake target `all'.
> make: `all' is up to date.
> 
> My questions are:
> 1.why remove a.c before taget all is built,so rebuild a.c twice when I run
> make the first time

See above.  Make is re-exec'ing itself due to the change in the .d file.
It removes the file once when building the .d, then re-execs, and
removes the file again after the build of "all".

> 2.why a.c doesn't rebuild when make knows 'a.c' doesn't exit

Because that's what it means to be an intermediate file (".INTERMEDIATE:
a.c").  See the description in the GNU make manual: an intermediate file
is not rebuilt unless one of its prerequisites is newer than its parent.
Here, a.c does not have any prerequisites.  It's basically never really
correct (at least I can't think of a situation where it would be
correct) to declare a "leaf" target such as a .c file to be
intermediate.


All your problems appear to stem from the auto-re-exec capability of
make when it rebuilds makefiles, and you seem to be using it exclusively
to get auto-generated dependencies.

You might consider switching to a more advanced method of auto-generated
dependencies, described here:

http://make.mad-scientist.net/autodep.html

This version doesn't rely on rebuilding included make snippets (in fact
it explicitly does NOT use them).

-- 
-------------------------------------------------------------------------------
 Paul D. Smith <address@hidden>          Find some GNU make tips at:
 http://www.gnu.org                      http://make.mad-scientist.net
 "Please remain calm...I may be mad, but I am a professional." --Mad Scientist




reply via email to

[Prev in Thread] Current Thread [Next in Thread]