Put simply:
It's the community, stupid.
Or:
If you have to pick, choose function over form (at least when it comes to build tools).
Ahem. Sorry, let's start from the beginning.
Like any group of super-smart programmers using a relatively new language, a lot of folks in the Clojure community have looked at existing build tools (the JVM space is the relevant one here, meaning primarily Maven and Ant, although someone will bark if I don't mention Gradle, too), and felt a rush of disdain. I'd speculate that this came mostly because of XML allergies, but perhaps also in part because when one has a hammer as glorious as Clojure, it's hard to not want to use it to beat away at every problem in sight. Ruby has rake, and python has easy_install, so it seems natural that Clojure should have its own build system that leverages the language's stellar capabilities – "just think of how simple builds could be given macros and such", one might think.
I can sympathize with that perspective, and I admit that I, too, once thought that a Clojure-based build system was an obvious move. This notion runs off the rails pretty quickly for one reason:
Handily enough, Clojure is a JVM language, so using all of the goodness that's been built up over the years in Maven-land is extraordinarily easy to do. This means you have to write less code, and you get to use more mature, well-tested, well-supported code and tools, allowing you to focus on building awesome Clojure apps, not dicking around with implementing shell invocation, or Java compilation, or deployment via scp, or whatever "simple" build task you need today that's been in Maven's quiver for 5 years.
As if that weren't enough, Sonatype has its Polyglot Maven project, where they are working on making it possible to drive Maven builds from your favorite language, be it Clojure, Ruby, Groovy, or Scala. For now, I stick to using XML POM files (they're incredibly well-supported by tons of JVM-land tools – code completion on dependency version numbers FTW); while I love s-expressions, I'm too happy to trade off a pinch of syntactic elegance in exchange for tons more capability.
With that said, let's see what building a Clojure app using Maven looks like. First, the demo, where I start with the simplest Maven POM for building Clojure projects, and add in a Maven plugin to wrap my application into an OS X .app bundle (also available in HD):
[vimeo http://vimeo.com/10431242]
For reference purposes, here's that simplest of all Maven POM files you can use for your own projects:
[sourcecode lang="clojure"] <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.snowtide</groupId> <artifactId>easy-maven</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>Easy Clojure Maven setup</name> <dependencies> <dependency> <groupId>org.clojure</groupId> <artifactId>clojure</artifactId> <version>1.1.0</version> </dependency> <dependency> <groupId>org.clojure</groupId> <artifactId>clojure-contrib</artifactId> <version>1.1.0</version> </dependency> </dependencies>
<build> <plugins>
<plugin>
<groupId>com.theoryinpractise</groupId>
<artifactId>clojure-maven-plugin</artifactId>
<version>1.3.2</version>
<executions>
<execution>
<id>compile-clojure</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin> </plugins>
</build>
<repositories> <repository>
<id>clojure</id>
<url>http://build.clojure.org/releases</url> </repository>
</repositories> </project> [/sourcecode]
If you're going to use Maven for your Clojure builds, here's some links: