[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: GNU make suggestion: did the dependency really change?
From: |
Henning Makholm |
Subject: |
Re: GNU make suggestion: did the dependency really change? |
Date: |
02 Nov 2001 22:49:09 +0100 |
Scripsit "Paul D. Smith" <address@hidden>
> %% Henning Makholm <address@hidden> writes:
> hm> Hm (checks it..) it works. Amazing. Where should I have looked for
> hm> that behavior in the documentation?
> However, (a) every make has always behaved this way,
OK, it turned out to be a case of my worldview needing adjustment.
Somehow I've managed to go through life thinking that make works in
three separate phases:
1. Read in the Makefile, expanding variables etc as you go
2. Compute which commands needs to be run, comparing timestamps
etc. (As in make -n)
3. Execute the predecided command sequence blindly, except if one
of them fails.
By the way, it is not *every* make that behaves this way. At least
/usr/ccs/bin/make on SunOS 5.7 doesn't. But the system make tools
from HP-UX and Digital UNIX do.
[`make && make -t`]
> hm> (at least sufficient enough to keep me from hacking around in the
> hm> source for make).
> :)
When I try it, I find that it is not quite sufficient. `make -t`
behaves weirdly, and now that I try it out, `make -n` behaves almost
as wierdly in a way I've never noticed before. Behold:
galar:~/foo$ cat Makefile
.SUFFIXES:
fil1: fil2 ; echo foo > fil1
fil2: fil3 ; echo foo > fil2
galar:~/foo$ ls -l fil?
-rw-r--r-- 1 makholm user 7 Nov 2 21:24 fil1
-rw-r--r-- 1 makholm user 9 Nov 2 21:20 fil2
-rw-r--r-- 1 makholm user 0 Nov 2 21:42 fil3
galar:~/foo$ make -n
echo foo > fil2
galar:~/foo$ make --version
GNU Make version 3.77, by Richard Stallman and Roland McGrath.
...
I had expected `make -n` to print
echo foo > fil2
echo foo > fil1
because those are the commands that would happen if I just ran `make`
without the -n. The manual describes the effect of -n as (node
"Instead of Execution"):
| "No-op". The activity is to print what commands would be used to
| make the targets up to date, but not actually execute them.
| [..]
| With the `-n' flag, `make' prints the commands that it would
| normally execute but does not execute them.
"Normally" (when we don't have those unusual commands that do not
change the modification date) fil2 would have its timestamp changed
by its command, so fil1 would need to be remade, and I'd clearly
expect `make -n` to tell me that (thus assuming that a file changes
when its commands are run).
(I've used `make -n` any number of times for C and C++ projects
without noticing that the final linking command is absent from the
output - but it is).
I gather from your comments that this behavior of GNU make is
intentional [1], but I think it should be mentioned in the
documentation for -n.
[1] Some other make tools do it the way I expected. These include
the native makes of Digital UNIX and SunOS. Interestingly,
Digital's make does check timestamps after actually running
commands, but *simulates* a timestamp update when doing
`make -n`.
Now, if I do `make -t` in the situation outlined above, fil2 gets
touched but fil1 doesn't. The output of `make -dt` concludes with
Must remake target `fil2'.
touch fil2
Successfully remade target file `fil2'.
Finished dependencies of target file `fil1'.
Dependency `fil2' is older than dependent `fil1'.
No need to remake target `fil1'.
make: `fil1' is up to date.
which is somewhat confusing - apparently make checks the timestamp
of a dependency *after* running commands for it (which is fine once
I get used to the idea :), but *before* it iself touches the file
with -t.
I cannot think of any way *this* could be the intended behavior...
--
Henning Makholm "They are trying to prove a hypothesis,
they are down here gathering data every season,
they're publishing results in peer-reviewed journals.
They're wrong, I think, but they are still scientists."