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?
Posted in Development | Tagged , , | View Comments