Setting up 0MQ for Clojure on OSX

ZeroMQ is a simple and robust asynchronous messaging layer.1 Unfortunately, using it with Clojure is far from simple. The steps below are the magic key that worked for me:

  • Starting out nice and slow, install the core zmq libraries and command line tools with homebrew:2
brew install zmq
  • With ZMQ installed, you’re ready to start building jzmq, the Java bindings. You’ll need to patch the homebrew formula for pkg-config, as jzmq requires the latest-and-greatest to build correctly3
brew edit pkg-config
require 'formula'

class PkgConfig <Formula
  homepage 'http://pkgconfig.freedesktop.org'
  url 'http://pkgconfig.freedesktop.org/releases/pkg-config-0.25.tar.gz'
  md5 'a3270bab3f4b69b7dc6dbdacbcae9745'

  def install
    paths=%W[#{HOMEBREW_PREFIX}/lib/pkgconfig /usr/local/lib/pkgconfig /usr/lib/pkgconfig /usr/X11/lib/pkgconfig].uniq
    system "./configure", "--with-pc-path=#{paths*':'}", "--disable-debug", "--prefix=#{prefix}"
    system "make install"
  end
end
  • At this point, you’ll need to copy one of the essential pkg-config files into a location that jzmq’s build tools can find.4
sudo cp /usr/local/Cellar/pkg-config/0.25/share/aclocal/pkg.m4 /usr/share/aclocal/pkg.m4
  • Now we’re ready to build jzmq. This will build the dylib you’ll need to actually use the bindings, and places it in /usr/local/lib.5
git clone git://github.com/zeromq/jzmq.git
cd jzmq
./autogen.sh
./configure
make
sudo make install
  • Getting closer! We’ll need the zmq.jar file produced during the build, so copy that into your project’s lib directory:6
cp ./src/zmq.jar /path/to/my/project/lib/zmq.jar
  • Now we can actually start setting up Clojure for ZMQ. Edit your leiningen project.clj file:
(defproject my-project "1.0.0-SNAPSHOT"
  :description "FIXME: write"
  :dependencies [[org.clojure/clojure "1.2.0"]
                 [org.clojure/clojure-contrib "1.2.0"]
                 [org.clojars.mikejs/clojure-zmq "2.0.7-SNAPSHOT"]]
  :dev-dependencies [[swank-clojure "1.2.1"]]
  ; This sets the 'java.library.path' property
  ; so Java can find the ZeroMQ dylib
  :native-path "/usr/local/lib")
  • Collect the leiningen dependencies:
lein deps
  • Start your swank server:
lein swank
  • Bask in the results with the canonical example:
(ns my-project.core
  (:use [org.zeromq.clojure :as zmq]))

(defn- string-to-bytes [s] (.getBytes s))
(defn- bytes-to-string [b] (String. b))

(defn test-zmq []
  (let [ctx (zmq/make-context 1)
	socket (zmq/make-socket ctx zmq/+upstream+)]
    (zmq/connect socket "tcp://127.0.0.1:5555")
    (while true
      (println (bytes-to-string (zmq/recv socket))))))

This process is definitely rough around the edges, but I hope it helps you get started quickly!

  1. Read this excellent ZeroMQ introduction if you’re not familiar with ZMQ. You’ll love it. ↩

  2. This guide is EXTREMELY brew-centric. If you’re running OS X, you should be using homebrew for dependency management. ↩

  3. There’s an open ticked to update pkg-config in the homebrew backlog, so this may be unnecessary soon. ↩

  4. This step should either be taken care of by homebrew, or by jzmq’s ./configure, but I wasn’t able to get it working. Please leave a note if you know how I could resolve this step! ↩

  5. This is another step that seems problematic. It would be best to just install the dylib straight into OS X’s Java extensions directory. Again, please leave a comment if you can help! ↩

  6. Another hacky step. I gather it’s possible to build jzmq with leiningen, but the native-deps dependency doesn’t seem to work with lein 1.3.0. Suggestions? ↩

blog comments powered by Disqus