[Top][All Lists]
[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/