The complexity of not lying to Makefiles
So, suppose that you are tired of lying to your Makefiles and want to fix the problem (in the abstract; you can't
completely fix your Makefiles, because it's not fixable in anything like
make). What does this take?
What you really need to capture is the state of the 'build inputs'. The build inputs are whatever goes in to creating the output, which is a lot more than just the source files involved; it also includes things like the test of the execution rule, the Makefile variables that go in to it, and even the programs that are run to create things.
(Actually, you don't care about the programs themselves so much as their
'interfaces' (in the programming language sense). You don't need to
rebuild something just because the version of
cp changed, because the
old and the new version still have the same interface and thus will
produce the same results.)
Capturing the state of build inputs is, in a sense, the easy bit; there is a lot of ways to capture and summarize the state of things. The difficult bit is figuring out just what is a build input. As my entry illustrates, you cannot rely on people to do this; it is too much work, especially if you are trying to really be thorough and truly solve the problem. Unfortunately, I don't think that anyone really knows how to do automated build analysis to capture this information, which leaves one somewhat out in the cold on the whole problem.
(My feeling is that automated analysis is only really practical in a captive build environment, but captive build environments rarely last for very long. Sooner or later they grow the ability to run external programs, and that's it for your ability to completely understand all build rules.)