Follow-up Comment #4, bug #66500 (group make): [comment #3 comment #3:] > This statement applies as make is traversing the graph and is considering a > target. When make is considering baz foo/tar exists and is older. > This is the typical issue when a recipie builds something other than $@.
Look at the log below. Make claims " Prerequisite 'foo/tar' is older than target 'baz'." even if it has just touched foo/tar. $ make --debug=v GNU Make 4.3 Built for x86_64-pc-linux-gnu Copyright (C) 1988-2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Reading makefiles... Reading makefile 'makefile'... Updating makefiles.... Updating goal targets.... Considering target file 'baz'. Considering target file 'foo/tar'. Considering target file 'foo'. Considering target file 'bar'. Finished prerequisites of target file 'bar'. No need to remake target 'bar'. Finished prerequisites of target file 'foo'. Prerequisite 'bar' is newer than target 'foo'. Must remake target 'foo'. mkdir foo mkdir: cannot create directory ‘foo’: File exists make: [makefile:5: foo] Error 1 (ignored) touch foo/tar Successfully remade target file 'foo'. Finished prerequisites of target file 'foo/tar'. Prerequisite 'foo' is older than target 'foo/tar'. No recipe for 'foo/tar' and no prerequisites actually changed. No need to remake target 'foo/tar'. Finished prerequisites of target file 'baz'. Prerequisite 'foo/tar' is older than target 'baz'. No need to remake target 'baz'. On the other hand, the POSIX make specification says: " The make utility attempts to perform the actions required to ensure that the specified targets are up-to-date. A target shall be considered up-to-date if it exists and is newer than all of its dependencies, or if it has already been made up-to-date by the current invocation of make (regardless of the target's existence or age). A target may also be considered up-to-date if it exists, is the same age as one or more of its prerequisites, and is newer than the remaining prerequisites (if any). 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. To ensure that a target is up-to-date, make shall ensure that all of the prerequisites of a target are up-to-date, then check to see if the target itself is up-to-date. If the target is not up-to-date, the target shall be made up-to-date by executing the rule's commands (if any). If the target does not exist after the target has been successfully made up-to-date, the target shall be treated as being newer than any target for which it is a prerequisite. " Once again: "To ensure that a target is up-to-date, make shall ensure that all of the prerequisites of a target are up-to-date, then check to see if the target itself is up-to-date." So, make should try to updata foo/tar, then check if foo/tar is newer than baz, and update baz if it is. This is what GNU make tries to do, but the check is incorrect due to timestamp caching. _______________________________________________________ Reply to this item at: <https://savannah.gnu.org/bugs/?66500> _______________________________________________ Message sent via Savannah https://savannah.gnu.org/
signature.asc
Description: PGP signature