"I think that djb redo will turn out to be the Git of build systems."
pozorvlak.livejournal.com
pozorvlak.livejournal.com
Overall, I quite like it. One downside of the current design that I see as being somewhat hard to fix is that it doesn't handle build commands with multiple outputs. There are klugey workarounds, but they require either lying to redo about the true dependencies (which always fills me with dread), or making parallel build unreliable.
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...
If my program needs to be dynamically linked with, say, OpenSSL, but rarely actually uses it, how does introducing strace into this situation help?
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?
This is something that seems like it could be handled by the file system:
> $ cat .redo/artifact-source/src/path/to/file.c > f572d396fae9206628714fb2ce00f72e94f2258f
Or the reverse (hash to source path).
I made such a thing for C++ years ago. It adds a header and a footer to your pure C++ build-script, compiles it, and then runs it (compiling your program). It also included extension libraries that did some more advanced things, such as detect local dependencies, but still was very toy-like and unpolished. I never advertised it widely, especially after I started to use Ruby instead of C++ for the project it was related to.
Still, the basic idea of including the build-system in source-form with ones code might be interesting to some people... at least makes it easy to fix, deliver, and extend.
http://sourceforge.net/project/shownotes.php?release_id=3730... (unix / linux only)
Now, there is a third important property, which is clarity. But clarity for a new-comer is less important than a clarity for a person that uses build system daily.
I investigated several alternatives to make for our C++ game framework and settled to Waf. It's quite complex and side-effect of that has caused that we haven't integrated many of our tools to build system, just because doing so requires deep understanding of Waf model. Which I haven't acquired, well, mainly because of laziness.
Thus, clarity can affect both correctness and speed in practical situations of lazy people like myself.
What I like about redo is the simplicity. Based on my initial experiences, it seems that aside multiple output files problem, it doesn't get in to your way.
If nothing else, they should never be merged because they are trying to provide a POSIX utility, which should always be: "Do one thing and do it well"
Is that really true? If so, that's pathetic and my respect for my fellow developers as largely competent professionals is misplaced.