Follow-up Comment #3, bug #40056 (project make): In response to Paul's 2013-09-22T07:15:04+0000 comment:
To be clear: my patch simply applies the .LOW_RESOLUTION_TIMESTAMP special target's logic (add 0.999999999 seconds to a timestamp that lacks nanosecond resolution) implicitly to all low-resolution timestamp files. That's it. My patch doesn't "always round up timestamps to the next second"; it just uses the same technique that .LOW_RESOLUTION_TIMESTAMP does. But I agree with you, in that I think .LOW_RESOLUTION_TIMESTAMP is both wrong and a hack. It's an attempt to work around the root problem with make's handling of timestamps: make incorrectly attributes additional precision on timestamps where no such precision exists. To illustrate why make's behavior is wrong, let's say that we are attempting to calculate the area of a rectangle. We have two measurements: 6.4 meters for length, and 3.78 meters for width. If we multiply these two measurements with a calculator, the calculator will produce: 6.4 × 3.78 = 24.192 The answer of 24.192 m² is clear, simple... and wrong. It is wrong because it implies precision that does not exist in the original measurements. Specifically, since the first factor has 2 significant digits and the second factor has 3, the final answer cannot contain more than 2 significant digits. So the correct answer to "what is the area of this rectangle?" is 24 m², not 24.192 m². This might seem non-intuitive, but it's easier to understand if you consider the accuracy range of the original measurements: the instrument used to measure the length was accurate only to a decimeter, while the instrument used to measure the width was accurate to a centimeter. So, accounting for measurement error, these are the minimum/maximum potential areas: 6.3 × 3.77 = 23.751 6.5 × 3.79 = 24.635 This is why we cannot be any more accurate that "24 m²" in our answer. The same principle is true for timestamp comparisons. Say that we have two different files, foo and bar, with the following timestamps: foo: 2013-09-23 15:55:01.292619574 bar: 2013-09-23 15:55:01 Internally, make converts these timestamps into nanoseconds since the epoch: foo: 1379966105292619574 bar: 1379966105000000000 If foo is a dependency of bar, and make needs to decide whether bar needs to be rebuilt, it will compare the timestamps, determine that 1379966105292619574 is greater (newer) than 1379966105000000000, and conclude that bar needs to be rebuilt. This logic is clear, simple... and wrong. It is wrong because in its comparison, make relied on the erroneous precision that it conferred onto bar, when it converted bar's timestamp to nanoseconds. But bar *has no such precision*. In order to perform timestamp comparisons correctly, make *must* constrain the granularity of its comparison to the precision of the least precise element being compared. In this example, since bar is precise to the second, and foo is precise to the nanosecond, that means that make must compare foo and bar only to the seconds to decide whether foo is more recent than bar. Thus, the arguably best way to correct make's behavior is to add a "precision" element to the "file" struct, and then take that precision into account when performing all timestamp comparisons. However, that would be a non-trivial change, and since this is the first time I've looked at make's source code, I'm not confident I can implement the change correctly. (Plus, I'm not going to commit to such a change unless I have some assurance that make's maintainers would be receptive to it.) That's why I just generalized the .LOW_RESOLUTION_TIMESTAMP special target's logic implicitly to all low-resolution timestamp files. I fully admit that doing so is a hack, but 1) it's no less of a hack than the existence of .LOW_RESOLUTION_TIMESTAMP to begin with, and 2) it produces more correct behavior than make exhibits currently. And to be clear, make's current behavior with respect to timestamp comparisons means that in our environment (dependencies on ext4; targets on ext3), make is broken to the point of being *unusable*. I'm not criticizing make's timestamp comparison logic because we are seeking "perfect" instead of "good enough"; I'm criticizing it because it produces incorrect, broken behavior. _______________________________________________________ Reply to this item at: <http://savannah.gnu.org/bugs/?40056> _______________________________________________ Message sent via/by Savannah http://savannah.gnu.org/ _______________________________________________ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make