I believe that I have found a bug present in both Make 4.2.1 (as shipped by Arch Linux) and in the latest git commit (214865ed5c66d8e363b16ea74509f23d93456707).
Here is a simple Makefile demonstrating the bug: all: a-derived.out .PHONY: all kindaclean: rm -f -- *.out clean: kindaclean rm -f -- a-derived.src .PHONY: kindaclean clean %.out: %.src { echo 'build'; date; ls -l $^; } > $@ a-derived.src: a.out { echo 'generate'; date; ls -l $^; } > $@ a-derived.out: a.out # Make sure that "a.out" isn't skipped as intermediate .SECONDARY: For clarity, here is the dependency graph; "==" indicates an explicit rule, "--" indicates an implicit rule: all >===> a-derived.out >---> a-derived.src >===> a.out >---> a.src `>=======================>' The bug is that when running $ echo foo > a.src $ make { echo 'build'; date; ls -l a.src; } > a.out { echo 'generate'; date; ls -l a.out; } > a-derived.src { echo 'build'; date; ls -l a-derived.src a.out; } > a-derived.out $ make kindaclean rm -f -- *.out $ make { echo 'build'; date; ls -l a.src; } > a.out { echo 'build'; date; ls -l a-derived.src a.out; } > a-derived.out The "a-derived.src" does not get updated, despite both of thes conditions being met: (1) its dependency "a.out" getting updated, and (2) it being used in a later recipe. We can instrument the Makefile to more explicitly demonstrate the failure: define sanitycheck if ! test -e $1; then \ echo '=> dependency "$(strip $1): $(strip $2)" skipped because dependent "$(strip $1)" does not exist'; \ elif ! test -e $2; then \ echo '=> dependency "$(strip $1): $(strip $2)" skipped because dependency "$(strip $2)" does not exist'; \ elif test $2 -nt $1; then \ echo '=> dependency "$(strip $1): $(strip $2)" failed because dependency "$(strip $2)" is newer than dependant "$(strip $1)"'; \ ls -l $1 $2; \ exit 1; \ else \ echo '=> dependency "$(strip $1): $(strip $2)" passed'; \ fi endef all: a-derived.out @$(call sanitycheck, a.out , a.src ) @$(call sanitycheck, a-derived.src , a.out ) @$(call sanitycheck, a-derived.out , a-derived.src ) .PHONY: all kindaclean: rm -f -- *.out clean: kindaclean rm -f -- a-derived.src .PHONY: kindaclean clean %.out: %.src { echo 'build'; date; ls -l $^; } > $@ a-derived.src: a.out { echo 'generate'; date; ls -l $^; } > $@ a-derived.out: a.out # Make sure that "a.out" isn't skipped as intermediate .SECONDARY: Which yields: $ echo foo > a.src $ make { echo 'build'; date; ls -l a.src; } > a.out { echo 'generate'; date; ls -l a.out; } > a-derived.src { echo 'build'; date; ls -l a-derived.src a.out; } > a-derived.out => dependency "a.out: a.src" passed => dependency "a-derived.src: a.out" passed => dependency "a-derived.out: a-derived.src" passed $ make kindaclean rm -f -- *.out $ # wait a momenent, so the timestamps are visibly different $ make { echo 'build'; date; ls -l a.src; } > a.out { echo 'build'; date; ls -l a-derived.src a.out; } > a-derived.out => dependency "a.out: a.src" passed => dependency "a-derived.src: a.out" failed because dependency "a.out" is newer than dependant "a-derived.src" -rw-r--r-- 1 lukeshu lukeshu 89 Feb 22 13:45 a-derived.src -rw-r--r-- 1 lukeshu lukeshu 85 Feb 22 13:47 a.out make: *** [Makefile:17: all] Error 1 -- Happy hacking, ~ Luke Shumaker _______________________________________________ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make