
On Fri, 2007-10-26 at 10:48 +0000, Duncan Coutts wrote:
So what's next...
We want to write some specifications, both of what make should do and some internal invariants about the graph.
A smattering of informal descriptions of properties: "globally up to date" Globally, the state after make has run should be such that every target is up to date with respect to it's dependencies. Thomas suggests a good way to check that that does not rely on the internals of the make algorithm or types is to generate a tree, write out corresponding files (in the pure Make monad) and supply a gen function based on the generated tree. Then we can check after make if all dependencies are up to date. So the point it we generate and keep a simple external dep tree (graph? dag?) and check make against that. "only rebuild what's necessary" A similar property is to say that after a build and touching a few files, we should only rebuild the bits that are necessary. For every action run, before the action is run there must exist a target and a dependency that are out of date with respect to each other. So actually this is expressed as a local property, not on the state after make has run. Perhaps we should express the "globally up to date" property in a local style. It might make pin-pointing offenders easier. Or do both. "no untracked dependencies" To a first approximation, an action should only read files that are listed as dependencies and only write files that are listed as targets. A better approximation would allow creating and deleting temporary files (files that did not previously exist and are not targets or dependencies in the graph), reading files that are indirect dependencies (think .hi files) and reading some "global constant system files" like libc.so, locale definitions etc. We can check this property if we record the beginning and end of actions in the Trace and include the complete list of dependencies and targets in the trace event (including dynamic dependencies and targets). Note that this property is something we really can check in a real build (at least on linux) using strace to get a trace of system calls. "only necessary dependencies" The opposite property is that there are no unnecessary dependencies or targets, that is listed dependencies/targets that are never read/written. It's not clear this is so important or will always be true. It is probably possible to have conditionals such that files are used or not depending on something. So if we go for this one we'd probably need per-rule exception lists/properties. Duncan