Friday, January 15, 2010

Manual Installation (not using ELPA) of swank-clojure

There appears to be a lot of discussion on getting slime and emacs integrated with Clojure similar to how it is with Common Lisp. For most setups, Technomancy has made it easy to quickly setup the IDE by installing Swank Clojure via ELPA in emacs. Those who don't like using ELPA or need to hack on the sources, need to install the software manually. I present my manual installation experiences and I hope it may be useful to others.

Obtaining Software

I relied on my distribution's package manager to install emacs and slime (as well as git, java, and everything else not listed) but the following packages,


are rapidly developed and at the moment are not best handled by my package manager so I installed them from source. To keep things organized, I downloaded the sources in their own directory.

mkdir ~/clj
cd ~/clj
git clone git://
git clone git://
git clone git://
git clone git://
git clone git://

I was now free to hack, but I needed to build them before use.

Building Software

Swank Clojure depends on Leiningen and Leiningen depends on Clojure so I needed to build that first.

I built clojure as specified in the readme.

cd ~/clj/clojure

I setup an installation directory for Clojure with a minimal folder structure. I don't know what recommended layout is but I copied my distribution's version of clojure.

cd ~/clj
mkdir -p runtime runtime/bin runtime/classes runtime/lib

I then populated the folders. In runtime/bin, I had a simple script

java -cp ~/clj/runtime/lib/clojure.jar clojure.main

and in runtime/lib I symlinked all the jars. At the time, the only clojure.jar was built so I linked it.

cd ~/clj/runtime/lib
ln -s ~/clj/clojure/clojure.jar

I tested clojure by by running the script.

Next I built clojure-contrib as specified in the README.

cd ~/clj/clojure-contrib
ant -Dclojure.jar=~/clj/runtime/lib/clojure.jar
ln -s ~/clj/clojure-contrib/clojure-contrib.jar ~/clj/runtime/lib

Next was Leiningen, which depends on itself so I needed to bootstrap it. The stable build script installs a version in the ~/.m2 folder. I put the script in my PATH and ran it.

cd ~/bin # this folder is in my path
chmod +x lein
mv lein lein-stable
lein-stable self-install

Next I built my checkouted Leiningen, added the checkouted lein into my path, and added the jar to ~/clj/runtime/lib

cd ~/clj/leiningen
lein-stable deps
ln -s ~/clj/leiningen/bin/lein ~/bin/lein
lein jar
ln -s ~/clj/leiningen/leiningen.jar ~/clj/runtime/lib

Next I built swank-clojure and linked the jar

cd ~/clj/swank-clojure
lein jar
ln -s ~/clj/swank-clojure/swank-clojure.jar ~/clj/runtime/lib

Next I needed to configure my .emacs file to swank-clojure and clojure-mode with some slight modifications in order to work with mismatched versions of clojure and clojure-contrib with swank-clojure

Reading ~/clj/swank-clojure/swank-clojure.el allowed me to understand all the configuration parameters for swank-clojure. I highly recommend reading that file if you want to tweak anything in swank. It's well written and has good documentation.

;; in the .emacs file, clojure configuration
;; to run slime, M-- M-x slime then type clojure

;;tells emacs where to find clojure-mode.el
(add-to-list 'load-path "~/clj/clojure-mode")
(require 'clojure-mode)

(setq swank-clojure-jar-home "~/clj/runtime/lib")
;; need to override default deps so self-install is not evoked
;; the URLs are honestly arbitrary, I essentially just removed
;; the version info so that the filenames match the filenames
;; of the jars I built
(setq swank-clojure-deps
      (list (concat ""
            (concat ""
            (concat ""
(add-to-list 'load-path "~/clj/swank-clojure")
(require 'swank-clojure)
;; needed for overriding default method for invoking slime
(ad-activate 'slime-read-interactive-args)

That was it. To run slime, I just typed in emacs, "M-- M-x slime" then "clojure". I use "M--" so I can still run SBCL if I need to.

Hopefully this information may be useful to the community.


  1. Hey, apparently clojure-contrib builds with maven now.

  2. Great instructions! clojure-contrib is failing to build with maven, however. Here's one of the many errors (I can e-mail the complete log if you're interested):

    ERROR in (test-loading-clojure-contrib-probabilities-finite-distributions) (run-test6283948914857299363.clj:44)
    Uncaught exception, not in assertion.
    expected: nil
    actual: clojure.lang.Compiler$CompilerException: java.lang.IncompatibleClassChangeError (finite_distributions.clj:160)
    at clojure.lang.Compiler.analyzeSeq (
    clojure.lang.Compiler.analyze (
    clojure.lang.Compiler.analyze (
    clojure.lang.Compiler$BodyExpr$Parser.parse (
    clojure.lang.Compiler$LetExpr$Parser.parse (
    Caused by: java.lang.IncompatibleClassChangeError: null
    at clojure.contrib.macro_utils/expand_fn (macro_utils.clj:139)
    clojure.contrib.macro_utils/expand_list (macro_utils.clj:187)
    clojure.contrib.macro_utils/expand_all (macro_utils.clj:196)
    clojure.core$map__4089$fn__4090.invoke (core.clj:1870)

  3. Updated section on building clojure-contrib.

    Next I built clojure-contrib as specified in the README.

    cd ~/clj/clojure-contrib
    ant -Dclojure.jar=~/clj/runtime/lib/clojure.jar
    ln -s ~/clj/clojure-contrib/clojure-contrib.jar ~/clj/runtime/lib