Of course, I'm completely biased :) I have my own build system called fbuild (http://github.com/erickt/fbuild) that's conceptually similar to fabricate/memoize. There's also mem (http://srp.github.com/mem/getting-started.html) and wonderbuild (http://retropaganda.info/~bohan/work/sf/psycle/branches/boha... -- although that link appears to be broken at the moment) if you're interested in some other projects that have similar roots.
I believe the key insight that we all independently made is that we can use the procedural execution stack for the dependency tree, and cache the function arguments and results to avoid work duplication. I believe this helps someone reason about what's going on in the build system compared to the declarative make systems because you can easily trace the inputs and outputs of some dependency.
Furthermore, you can do some pretty interesting things with this model if you push this idea. It's pretty simple to do integrated configuration and building. For instance in fbuild, I can do (fbuild uses python3 for it's host language):
import fbuild.builders.c
import fbuild.config.c.linux
def build(ctx):
# make a c compiler.
builder = fbuild.builders.c.guess_static(ctx)
# check if the system supports epoll
if fbuild.config.c.linux.sys_epoll_h(builder).header:
use_epoll = True
else:
use_epoll = False
builder.build_exe('foo', ['foo.c'],
defines=['USE_EPOLL' if use_epoll else 'USE_SELECT'])
I don't think many of the new build systems have looked into the configuration issue yet, which is a shame. I'd love to get some more ideas out there.In fact, they have an example of using gcc to generate header-file dependencies for C. A command-line tool that ran a command and spat out what files it accessed (via strace, dynamic library imposition, or even crazier methods like interpreting the binary) would hook into this system fairly seamlessly.
and what about systems that don't have strace, like BSD or OSX or solaris or windows? there's dtrace on those platforms (minus windows), which requires root, and requiring root access for dependency resolution isn't exactly a great idea.
It can be a pain, but it's really not that hard to handle if your build system provides a way to abstract out build patterns.
I've used ktrace to help create minimal jail environments, quite handy: http://www.aagh.net/files/mkjail
Suddenly make is starting to seem pretty nice...
moreover, how can you run strace to figure out dependencies on a program that hasn't been built yet? how does it determine when new dependencies are added?
If my program needs to be dynamically linked with, say, OpenSSL, but rarely actually uses it, how does introducing strace into this situation help?