URL: <http://savannah.gnu.org/bugs/?46596>
Summary: Timestamp check behaviour difference in clean build and rebuild on rules without recipes Project: make Submitted by: stefanb Submitted on: Thu 03 Dec 2015 07:58:39 AM GMT Severity: 3 - Normal Item Group: Bug Status: None Privacy: Public Assigned to: None Open/Closed: Open Discussion Lock: Any Component Version: 4.1 Operating System: None Fixed Release: None Triage Status: None _______________________________________________________ Details: We encountered a difference how timestamps are handled between clean builds and rebuild depending if a rule has a recipe or not. If a rule doesn't have a recipe GNU make doesn't check the timestamp of the dependency correctly and therefore fails to trigger recipes from dependent rules. I have checked GNU make 3.81, 4.0 and 4.1: they are all affected by this issue. I've attached 3 makefiles that highlight the problem. We have * file "a" that depends on file "b" * file "b" is one of the files generated when file "d" is updated * the target for dependency "d" is file/.PHONY target "c" * the empty rule "b: c" makes sure that the dependencies are correct, i.e. when we ask for "a" the rule for "c" is triggered Without recipe attached to rule "b: c" the file "a" is not updated on first rebuild, only on the second one. Example 1 uses a .PHONY target for "c", example 2 does not. The example output is generated with make 4.1 to have the "--trace" option available. Example 1: wrong execution on rebuild: $ make --version GNU Make 4.1 Built for x86_64-unknown-linux-gnu ... # clean build $ make clean rm -f a b c d e $ make --no-print-directory --trace Makefile:21: target 'c' does not exist make -f Makefile2 Makefile2:8: target 'd' does not exist touch d Makefile2:5: update target 'b' due to: d cp d b Makefile:7: update target 'a' due to: b cp b a # rebuild without source change $ make --no-print-directory --trace Makefile:21: target 'c' does not exist make -f Makefile2 make[1]: Nothing to be done for 'all'. # 1st rebuild after source change $ touch d $ make --no-print-directory --trace Makefile:21: target 'c' does not exist make -f Makefile2 Makefile2:5: update target 'b' due to: d cp d b # 2nd rebuild after source change $ make --no-print-directory --trace Makefile:21: target 'c' does not exist make -f Makefile2 make[1]: Nothing to be done for 'all'. Makefile:7: update target 'a' due to: b cp b a # 3rd rebuild after source change $ make --no-print-directory --trace Makefile:21: target 'c' does not exist make -f Makefile2 make[1]: Nothing to be done for 'all'. # check that other target doesn't trigger phony target $ make --no-print-directory --trace all2 Makefile:24: target 'e' does not exist touch e Example 1: correct execution on rebuild by adding a no-op ":" recipe # clean build $ make clean rm -f a b c d e $ make --no-print-directory --trace _workaround1:=1 Makefile:21: target 'c' does not exist make -f Makefile2 Makefile2:8: target 'd' does not exist touch d Makefile2:5: update target 'b' due to: d cp d b Makefile:14: update target 'b' due to: c : Makefile:7: update target 'a' due to: b cp b a # rebuild without source change $ make --no-print-directory --trace _workaround1:=1 Makefile:21: target 'c' does not exist make -f Makefile2 make[1]: Nothing to be done for 'all'. Makefile:14: update target 'b' due to: c : # 1st rebuild after source change $ touch d $ make --no-print-directory --trace _workaround1:=1 Makefile:21: target 'c' does not exist make -f Makefile2 Makefile2:5: update target 'b' due to: d cp d b Makefile:14: update target 'b' due to: c : Makefile:7: update target 'a' due to: b cp b a # 2nd rebuild after source change $ make --no-print-directory --trace _workaround1:=1 Makefile:21: target 'c' does not exist make -f Makefile2 make[1]: Nothing to be done for 'all'. Makefile:14: update target 'b' due to: c : Example 1: correct execution on rebuild by adding an empty recipe # clean build $ make clean rm -f a b c d e $ make --no-print-directory --trace _workaround2:=1 Makefile:21: target 'c' does not exist make -f Makefile2 Makefile2:8: target 'd' does not exist touch d Makefile2:5: update target 'b' due to: d cp d b Makefile:7: update target 'a' due to: b cp b a # rebuild without source change $ make --no-print-directory --trace _workaround2:=1 Makefile:21: target 'c' does not exist make -f Makefile2 make[1]: Nothing to be done for 'all'. # 1st rebuild after source change $ touch d $ make --no-print-directory --trace _workaround2:=1 Makefile:21: target 'c' does not exist make -f Makefile2 Makefile2:5: update target 'b' due to: d cp d b Makefile:7: update target 'a' due to: b cp b a # 2nd rebuild after source change $ make --no-print-directory --trace _workaround2:=1 Makefile:21: target 'c' does not exist make -f Makefile2 make[1]: Nothing to be done for 'all'. Example 2: wrong execution on rebuild: # clean build $ make -f Makefile.no-phony clean rm -f a b c d e # rebuild without source change $ make -f Makefile.no-phony --trace Makefile.no-phony:23: target 'd' does not exist touch d Makefile.no-phony:19: update target 'c' due to: d touch c touch b Makefile.no-phony:7: update target 'a' due to: b cp b a # 1st rebuild after source change $ touch d $ make -f Makefile.no-phony --trace Makefile.no-phony:19: update target 'c' due to: d touch c touch b # 2nd rebuild after source change $ make -f Makefile.no-phony --trace Makefile.no-phony:7: update target 'a' due to: b cp b a # 3rd rebuild after source change $ make -f Makefile.no-phony --trace make: Nothing to be done for 'all'. Example 2: correct execution on rebuild by adding a no-op ":" recipe # clean build $ make -f Makefile.no-phony clean rm -f a b c d e $ make -f Makefile.no-phony --trace _workaround1:=1 Makefile.no-phony:23: target 'd' does not exist touch d Makefile.no-phony:19: update target 'c' due to: d touch c touch b Makefile.no-phony:14: update target 'b' due to: c : Makefile.no-phony:7: update target 'a' due to: b cp b a # rebuild without source change $ make -f Makefile.no-phony --trace _workaround1:=1 make: Nothing to be done for 'all'. # 1st rebuild after source change $ touch d $ make -f Makefile.no-phony --trace _workaround1:=1 Makefile.no-phony:19: update target 'c' due to: d touch c touch b Makefile.no-phony:14: update target 'b' due to: c : Makefile.no-phony:7: update target 'a' due to: b cp b a # 2nd rebuild after source change $ make -f Makefile.no-phony --trace _workaround1:=1 make: Nothing to be done for 'all'. Example 2: correct execution on rebuild by adding an empty recipe # clean build $ make -f Makefile.no-phony clean rm -f a b c d e $ make -f Makefile.no-phony --trace _workaround2:=1 Makefile.no-phony:23: target 'd' does not exist touch d Makefile.no-phony:19: update target 'c' due to: d touch c touch b Makefile.no-phony:7: update target 'a' due to: b cp b a # rebuild without source change $ make -f Makefile.no-phony --trace _workaround2:=1 make: Nothing to be done for 'all'. # 1st rebuild after source change $ touch d $ make -f Makefile.no-phony --trace _workaround2:=1 Makefile.no-phony:19: update target 'c' due to: d touch c touch b Makefile.no-phony:7: update target 'a' due to: b cp b a # 2nd rebuild after source change $ make -f Makefile.no-phony --trace _workaround2:=1 make: Nothing to be done for 'all'. _______________________________________________________ File Attachments: ------------------------------------------------------- Date: Thu 03 Dec 2015 07:58:39 AM GMT Name: Makefile Size: 233B By: stefanb Example makefiles <http://savannah.gnu.org/bugs/download.php?file_id=35624> ------------------------------------------------------- Date: Thu 03 Dec 2015 07:58:39 AM GMT Name: Makefile2 Size: 48B By: stefanb Example makefiles <http://savannah.gnu.org/bugs/download.php?file_id=35625> ------------------------------------------------------- Date: Thu 03 Dec 2015 07:58:39 AM GMT Name: Makefile.no-phony Size: 185B By: stefanb Example makefiles <http://savannah.gnu.org/bugs/download.php?file_id=35626> _______________________________________________________ Reply to this item at: <http://savannah.gnu.org/bugs/?46596> _______________________________________________ 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