code programming

Horn – how to resolve a circular build dependency

Recently I’ve been working with Paul Cowan and others on the Horn build project (Horn source is on Google Code). Horn is a .Net build tool in a similar vein to Portage from Gentoo, Ruby Gems or Python Eggs, in that it provides a simple interface to search, fetch, build and install a variety of open source projects. A few weekends ago, the two of us tackled one of the biggest blockers to the project – namely the interdependency between Castle and NHibernate. Paul’s take on this can be found here:

The net result is that we are able to build Nhibernate and the relevant parts of castle.

The Software Simpleton: Dividing The Castle

As I originally wrote the dependency resolution code for horn I thought I should add some thoughts on this, particularly with the problems between Castle and NHibernate.

At the basic level, a dependency exists whenever a project uses another for functionality. For horn itself, these dependencies include castle and log4net, so in order to successfully build horn, we need to first build castle and log4net. We use a tree structure to represent this, with the root being the package you want (e.g. horn), and the children of each node being the projects it depends on, down to the leaves that don’t depend on any other package. To determine build order, we do a breadth first traversal of the tree so that all the leaves are built first, followed by their parents, and so on. The results of each build are copied into a specified location so that the parent package has access to the built assemblies.

The tree structure allows us to determine circular dependencies as it is being constructed by seeing if any package depends on itself directly or via other packages. We simply check to see if the package is a parent of itself in the tree.

For full details, see Paul’s post above, but the problem with Castle and NHibernate comes from the fact that Castle depends on NHibernate and NHibernate depends on Castle, so we end up with a circular reference. To resolve the issue in this case, as described in the post above, we had to split the Castle.DynamicProxy2 library out of the Castle package into its own package, with a custom build file. NHibernate now has Castle.DynamicProxy2 as its dependency, which does not lead to a circular reference, and the rest of Castle depends on NHibernate.

The project is gearing up for a beta release, so if you fancy helping to batter the software into shape, with bug fixing, testing, writing package definitions or anything else, feel free to jump on over and lend a hand. No guarantees or warranties on it yet, but I’ll be sure to post again once the public beta is ready.

Blogged with the Flock Browser

One reply on “Horn – how to resolve a circular build dependency”

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.