On Thu, Dec 6, 2012 at 2:02 PM, Mikulas Patocka <miku...@artax.karlin.mff.cuni.cz> wrote: > The apparent problem is that after make rebuilds b, it compares b's time > with a's time, finds that the times are equal (because a was touched just > before make was run) and doesn't rebuild a. > > I think it is a bug - when b is finished, make should find out whether the > rule for b modified the file b (if b's time is greater or equal than the > time when the rule for b was started, then b may have been modified) and > rebuild a in this case.
That's not the rule that make has always followed and, indeed, is required by the standard to follow. To quote POSIX: The make utility attempts to perform the actions required to ensure that the specified targets are up-to-date. A target is considered out-of-date if it is older than any of its prerequisites or if it does not exist. The make utility shall treat all prerequisites as targets themselves and recursively ensure that they are up-to-date, processing them in the order in which they appear in the rule. The make utility shall use the modification times of files to determine whether the corresponding targets are out-of-date. The fact that the timestamp on a prerequisite has changed do *not* mean that it's newer than the target; it may have been copied from some other file which, while newer, is still older than the target file. So the change to the make algorithm described in the paragraph above that starts "I think it is a bug" would not be correct; something more precise about what timestamps would be considered "newer" would be necessary. Note that this problem doesn't arise on systems with high precision file timestamps. Many systems have provided those since the mid 90's; I'm appalled that the modern system that process the involved shell commands fast enough for this to regularly be a problem don't provide microsecond or better timestamp precision. > This bug is causing real-world problems in automake-generated Makefiles. > This is a simplified piece of Makefile from automake: > all : config.h > $(MAKE) all-am > > config.h : stamp-h1 > echo build config.h > > stamp-h1 : config.h.in > echo build stamp-h1 > rm -f stamp-h1 > touch config.h > touch stamp-h1 > > config.h.in : am__configure_deps > echo build config.h.in > rm -f stamp-h1 > touch config.h.in > > all-am : > echo ALL-AM > > Now, if you run this script, you trigger the bug: > > touch config.h.in;sleep 1;touch am__configure_deps;sleep 1;touch config.h > stamp-h1;make > > - you see "build config.h.in", but the other files are not rebuild and > all-am is executed > (the essential thing to trigger the bug is that make is run in the same > second in which config.h and stamp-h1 were created) ... > Another possible solution for this bug would be to remove rm -f stamp-h1 > from config.h.in rule, but there is some complex explanation in > /usr/local/share/automake-1.12/am/remake-hdr.am why rm -f stamp-h1 is > there so it would likely fix one bug and trigger another one. Hmm, adding a "sleep 1" after that rm -f and before the touch config.h.in would work without reintroducing the issue described in that explanation, no? Philip Guenther _______________________________________________ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make