Ian Bicking created an article with the same title as this article where he describes writing a build system to deploy software. And nothing spells fun like everybody piling on with their own experiences creating a build system!
I created Buildit after taking a run at the same problem via pymake . Essentially both are Make clones where the control system is Python rather than some domain-specific language. Pymake was no fun to use because it left the problem of properly computing dependent variable replacements up to the user. For example, if you have a path named "base_dir", pymake would make its users join that explicitly in Python to create "base_dir"-relative variables "etc_dir", "var_dir", etc. Buildit does a much better job of this; this job can be done in the configuration language itself and thus supplanted Pymake.
Buildit is a perhaps slightly-too-literal port of Make to Python. It's perhaps a better library on which to base a proper developer build system than it is a build system in its own right. When I developed it, I saw building software environments in terms of Make-like tasks. Since then I've seen other ways to do it, which has been useful. If I were to do it all over, I'd do it differently.
But all in all, using zc.buildout has been a pretty nice experience. I suppose there's a bit of "I finally get it" hiding in that observation.
I was never completely comfortable with the way buildit worked. There's probably a better way to do all of it. I dunno what that is. It's hard to make a system that is meant to be extended to do imperative things from a completely declarative configuration. zc.buildout doesn't really do all of it right either, but it gets it more right than buildit does as an extensible framework. In any case, I've mostly given up on buildit, and we've switched over to using zc.buildout for new builds. I am usually the "build bitch" on any given project we do, so I get to choose the tool. Any innovation I put into a buil systems will likely go into creating zc.buildout recipes.
Ian describes fassembler as "does a list of things, top to bottom [ .. with ... ] no effort [ .. towards ..] detecting changes in the build, or changes in the settings, or anything else". In that case, why bother writing a build system at all and instead just use a shell script? I don't think Ian actually meant this, I think fassembler does detect changes in the build (is this file already written?, do I need to make this symlink?, etc). So it does make the same sorts of decisions that buildit and Make do in order to be able to skip work because redoing it would cause more problems than it solved; maybe it is just more interactive about how to deal with conflicts: it asks the user. That's sort of ok by me. I'd actually rather that it just gave up and exited so it could be used in a buildbot sort of thing, but it's not really all that important either way.
I think continued innovation in Python build systems is important. Nothing we have is near perfect.
The most important features of a development build system (as we use it) is are:
Everything else is sort of secondary. We usually end up using the development build system to deploy to production too, and there are some different requirements driving "important features" there, but most of the value we get out of automated builds is by avoiding fallout from manually configured environments on developer systems.
This was probably a big part of my frustration with BuildIt. When I used zc.buildout it was also horrible, though I'm sure it's improved some (though whether it has improved *enough* is a separate issue).
Replies to this comment