A recursive build design trick that I have seen before and am now
dealing with is where a bunch of work (target commands are being
executed) is done only to find that the target is not actually modified.
One example of this is generating a export list of symbols for a
shared library. Specifically, even though the object files that
go into a shared library have changed, possibly quite so, the
'external' symbol list including all argument specifications (ansi C)
has not.
When this is so, no down stream executables or other shared libs
need to be relinked with the new shared library since none of the
external symbols have changed. In recursive build systems, a
common trick is that the make process of the shared library directory
ends up not modifying the library's export list file while it does
modify the shared library itself. Then, when the build recurses into
another directory, creating a new instance of a new DAG, recursive
targets that depend on the export file (anything that links the
library!) will see the old export file and not relink. Targets
that depend on the shared library, like unit tests, 'make install'
targets and the like, will see a new .so and re-run.