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!

blog comments powered by Disqus