help-make
[Top][All Lists]
Advanced

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

Re: multiple/hidden targets again


From: John Graham-Cumming
Subject: Re: multiple/hidden targets again
Date: Wed, 22 Feb 2006 11:38:16 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040208 Thunderbird/0.5 Mnenhy/0.6.0.104

Alexander Frink wrote:
If I change the line
foo.h bar.h: foobar
to an empty command
foo.h bar.h: foobar ;
everything works as expected (see debug output below), however
according to the manual "The only reason this is useful is to prevent
a target from getting implicit commands", which is not the case here.

So, is this a bug, a feature or am I doing anything wrong?

It's a feature/bug. Basically if you don't add the ; then Make thinks there are no commands associated with building foo.h and bar.h and so it doesn't check to see if they've been updated (which the were by the foobar rule). This means that the time stamps that GNU Make is keeping internally will not match what's on the disk.

When you add the ; then GNU Make takes a look on disk and notices that the .h files have been updated and hence the correct work is done.

If you take a look at the strace output for the make where it only builds the bar.o branch and apparently ignores foo.o (i.e. the case where you have touched input, but do not have the ; in the rule):

stat64("program", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
stat64("foo.o", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
stat64("foo.c", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
stat64("foo.h", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
stat64("foobar", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
stat64("input", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
creating foo.h
touch foo.h
creating bar.h
touch bar.h
creating foobar
touch foobar
stat64("foobar", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
stat64("bar.o", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
stat64("bar.c", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
stat64("bar.h", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
compiling bar
touch bar.o
stat64("bar.o", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
linking
touch program
stat64("program", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0

You'll notice it checking in sequence the file time for program, foo.o, foo.c and foo.h. At this point GNU Make will cache those time stamps. It then looks at foobar and input and runs the foobar rule. Straight after that, it runs the foobar rule and because there were commands it will check the timestamp on $@ (i.e. foobar).

GNU Make then starts up the bar.o branch and checks bar.o, bar.c and bar.h. Since this is the first time it's looked at bar.h it gets the new time from the touch bar.h that was just performed and hence bar.o gets built and so does program.

Then when you type 'make' again and it builds foo.o and hence program it's because it now sees the new foo.h time (which is newer than foo.o) because the cache is empty again (you just started make) and hence you get the behaviour you see.

Add that ; back and GNU Make thinks there are commands, and refreshes its directory cache and does the right thing.

I talk some more about GNU Make's directory cache and its affect on the $(wildcard) function in the article "The trouble with $(wildcard)": http://www.cmcrossroads.com/ubbthreads/showflat.php?Cat=&Board=cmbasics&Number=47060

John.
--
John Graham-Cumming
address@hidden

Home: http://www.jgc.org/
Blog: http://www.jgc.org/blog/

POPFile: http://getpopfile.org/
GNU Make Standard Library: http://gmsl.sf.net/
GNU Make Debugger: http://gmd.sf.net/
Fast, Parallel Builds: http://www.electric-cloud.com/

Sign up for my Spam and Anti-spam Newsletter
at http://www.jgc.org/




reply via email to

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