While looking through some old bugs in Savannah and trying to reproduce them I ran across this change in behavior between GNU make 4.3 and current Git master HEAD:
$ cat Makefile 1.all: 1.q ; touch $@ %.q: 1.r ; touch $@ %.r: ; touch $@ Note here, 1.r is mentioned explicitly in the makefile, but only as a prerequisite of a pattern rule. GNU make 4.3 treats this as an intermediate file: $ rm -f 1.* ; make -r touch 1.r touch 1.q touch 1.all rm 1.r In current master HEAD, it is not considered intermediate: $ rm -f 1.* ; ~/src/make/make -r touch 1.r touch 1.q touch 1.all This seems OK, because the docs are pretty clear that if a file is mentioned explicitly as a prerequisite it's not intermediate with no special-casing of prerequisites of pattern targets. In any event this change needs to be noted in NEWS. However, it seems that even forcing the file to be considered intermediate does not work in master: $ cat Makefile 1.all: 1.q ; touch $@ %.q: 1.r ; touch $@ %.r: ; touch $@ .INTERMEDIATE: 1.r $ rm -f 1.*; make -r touch 1.r touch 1.q touch 1.all Investigating it appears that the reason is that the 1.r target is marked as secondary: 1.r: # Implicit rule search has been done. # Implicit/static pattern stem: '1' # File is an intermediate prerequisite. > # File is secondary (prerequisite of .SECONDARY). # Last modified 2021-12-29 13:23:54.184652114 # File has been updated. # Successfully updated. This prevents it from being removed even though it's been marked intermediate. This happens here in pattern_search(): /* We don't want to delete an intermediate file that happened to be a prerequisite of some (other) target. Mark it as secondary. We don't want it to be precious as that disables DELETE_ON_ERROR etc. */ if (f != 0) f->secondary = 1; else f = enter_file (imf->name); In previous versions of make, the then-branch is not taken here and secondary is not set. In master, it is. This is just not a good idea anyway, and now that we have the is_explicit value in the file structure we don't need it so I removed that code. Unfortunately is_explicit is not correctly preserved in pattern_search() so I fixed this (plus the above tests) and now everything seems to pass. I suspect that we have too many options controlling explicit / intermediate / secondary / notintermediate. We should probably take a comprehensive look at these values and minimize them if possible.