Building Clojure Projects with Leiningen

clojure-iconEverybody who once used Java, struggled with Java’s classpath at some point during their career. You have to put all the right paths in there, the right .jar files and so on, both when compiling and running your Java project. To make this somewhat simpler you typically end up doing it either in an IDE, or using a tool like Ant or Maven. These are pretty heavy weight tools, and the latter too involve writing XML, which hardly anybody does for fun anymore.

Leiningen is a simple build tool for Clojure, based on Maven (I’m pretty sure). It offers a simple, Clojuresque way of constructing build files for your Clojure projects (which run on the JVM).

To install Leiningen you only have to download one fileand put it in some directory that’s on your PATH:

cd ~/bin wget http://github.com/technomancy/leiningen/raw/stable/bin/lein chmod +x lein

You then do a self-install:

lein self-install

This will dowload a number of jar files, including Clojure itself, so you do not even have to have Clojure installed at this point.

To make a new project, create a directory for it, e.g. helloworld:

mkdir helloworld mkdir helloworld/src

In the source directory you put your source files, for instance a helloworld/src/helloworld.clj:

(ns helloworld   (:gen-class))   (defn -main [& args]   (println "Hello world!"))

Then, in the helloworld/directory, create a project.clj file:

(defproject helloworld "0.1"     :dependencies [[org.clojure/clojure                      "1.1.0-master-SNAPSHOT"]                    [org.clojure/clojure-contrib                       "1.0-SNAPSHOT"]]     :main helloworld)

The :main there defines namespace containing your -main function (analogous to the typical public static void main(...)), if any. Then, from the helloworld directory you run Leiningen:

$ lein compile

[copy] Copying 2 files to /.../helloworld/lib

Compiling helloworld

And subsequently we can build a .jar for it, or even an uberjar, which will create a big jar file for easy distribution, also containing all of its dependencies (including Clojure itself): 

`$ lein uberjar`
`Unpacking clojure-1.1.0-alpha-20091113.120145-2.jar`
`Unpacking clojure-contrib-1.0-20091114.050149-13.jar`
`Compiling helloworld`
`      [jar] Building jar: helloworld.jar`
`$ java -jar helloworld.jar `
`Hello world!`

Leiningen has some other tasks as well:

  • lein deps, installs dependencies in lib/
  • lein test [PRED], runs the project’s tests, optionally filtered on PRED
  • lein compile, ahead-of-time compiles into classes/
  • lein repl, launches a REPL with the project classpath configured
  • lein clean, removes all build artifacts
  • lein jar, creates a jar of the project
  • lein uberjar, creates a standalone jar that contains all dependencies
  • lein pom, outputs a pom.xml file for interop with Maven
  • lein install, installs in local repo (currently requires mvn)
  • lein help [TASK], shows a list of tasks or help for a given TASK

Enjoy!