Introduction

ZeroMQ is an open source library widely used by programmers around the world. Its Wikipedia definition is as follows: “ZeroMQ (also spelled ØMQ, 0MQ or ZMQ) is a high-performance asynchronous messaging library aimed at use in scalable distributed or concurrent applications. It provides a message queue, but unlike message-oriented middleware, a ZeroMQ system can run without a dedicated message broker. The library is designed to have a familiar socket-style API.”

On ZeroMQ’s website, the community has provided build instructions for the Android platform (http://zeromq.org/build:android). However, those instructions are focused on ARM* architecture, and developers will meet build failure when they try to build the x86 version of ZeroMQ library by following the instruction step by step. That is why this article has been written.

Build Environment Preparation

The first goal in building ZeroMQ is to create a separate standalone tool chain for x86 that relies on Android NDK.

Download and install the latest Android NDK from:

http://developer.android.com/tools/sdk/ndk/index.html. In this article we use android-ndk-r10d-linux-x86_64. Fix a known issue in make-standalone-toolchain.sh, by applying the patch mentioned in https://code.google.com/p/android/issues/detail?id=74145. Without this patch the build will fail in the next step. Generate a standalone tool chain for the Android x86 platform.



./home/xxx/android-ndk-r10c/build/tools/make-standalone-toolchain.sh --arch=x86 --toolchain=x86-4.9 --install-dir=/home/xxx/android-standalone-toolchain-x86



You should follow the next two suggestions to avoid unexpected build problems:

Generate a single x86 tool chain in a separate directory. Don’t mix the x86 tool chain and the ARM tool chains in one directory. Install the standalone tool chain in your /home directory, to help avoid root/no-root authority issues. Configure the environment variables.



export PATH=/home/xxx/android-standalone-toolchain-x86/bin:$PATH export OUTPUT_DIR=/home/xxx/tmp/zeromq-android



Build ZeroMQ for Android x86

The following steps will show you how to build ZeroMQ along with Jzmq and its adjoining JAR, to be directly usable in Android and loaded into an APK file.

Download the source code and build ZeroMQ 3.x.



mkdir /home/xxx/tmp cd /home/xxx/tmp git clone https://github.com/zeromq/zeromq3-x.git cd zeromq3-x/ ./autogen.sh ./configure --host=i686-linux-android --prefix=$OUTPUT_DIR LDFLAGS="-L$OUTPUT_DIR/lib" CPPFLAGS="-fPIC -I$OUTPUT_DIR/include" --enable-static --disable-shared LIBS="-lgcc" make make install Download the source code and build jzmq.



cd /home/xxx/tmp git clone https://github.com/zeromq/jzmq.git cd jzmq/ ./autogen.sh ./configure --host=i686-linux-android --prefix=$OUTPUT_DIR LDFLAGS="-L$OUTPUT_DIR/lib" CPPFLAGS="-fPIC -I$OUTPUT_DIR/include" --disable-version --with-zeromq=$OUTPUT_DIR LIBS="-lpthread -lrt" make make install

If you see a failure during the execution of “./configure”, remove LIBS="-lpthread –lrt" and try again. Copy libjzmq.so and zmq.jar files to your desired directory, and now ZeroMQ has been built successfully!

cp /home/xxx/tmp/zeromq-android/lib/libjzmq.so /home/xx/tmp/ cp /home/xxx/tmp/zeromq-android/share/java/zmq.jar /home/xx/tmp/

An example using ZeroMQ in Android x86

You can now start using ZeroMQ in your Android applications. Here is a simple step-by-step example that describes how to use ZeroMQ in implementing message interaction between the ZeroMQ client and the ZeroMQ server. Some of this sample code is from the ZeroMQ official guide and wrapped into the Android project.

Copy libjzmq.so into the directory “DemoJZMQ/jni/”, and copy zmq.jar into the directory “DemoJZMQ/libs/”. Add the script below to Android.mk

LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libjzmq LOCAL_SRC_FILES := libjzmq.so include $(PREBUILT_SHARED_LIBRARY) Add the script below to Application.mk.

APP_ABI := x86 Implement the server side function.

public void startZMQserver() throws Exception { ZMQ.Context context = ZMQ.context(1); // Socket to talk to clients responder = context.socket(ZMQ.REP); responder.bind("tcp://*:" + SERVER_PORT); printLog("Server", "Started"); while (!Thread.currentThread().isInterrupted()) { // Wait for next request from the client byte[] request = responder.recv(0); printLog("Server", "Received:" + new String(request)); // Do some 'work' Thread.sleep(1000); // Send reply back to client String reply = "World"; responder.send(reply.getBytes(), 0); printLog("Server", "Response send."); } responder.close(); context.term(); }

Implement the client side function.

public void startZMQclient() throws Exception { ZMQ.Context context = ZMQ.context(1); // Socket to talk to server printLog("Client", "Connecting to ZMQ server…"); requester = context.socket(ZMQ.REQ); requester.connect("tcp://" + SERVER_IP + ":" + SERVER_PORT); printLog("Client", "Connected to server."); for (int requestNbr = 0; requestNbr != 10; requestNbr++) { String request = "Hello"; printLog("Client", "Sending Hello " + requestNbr); requester.send(request.getBytes(), 0); byte[] reply = requester.recv(0); printLog("Client", "Received " + new String(reply) + " " + requestNbr); } requester.close(); context.term(); }

Run the example app on a device, click the “start server” button first, and then click “start client”. From “adb logcat” you can see the execution results (Figure 1) that show when the client sends a “Hello” to the server, the server responds “World” back to the client 10 times.

Figure 1. Demo JZMQ start screen with the log file example.

Summary

This article describes how to compile the ZeroMQ library for the Android x86 platform step by step. Also provided is a simple example using message transfer to show how to use ZeroMQ in Android applications. As mentioned above, the key point in compiling ZeroMQ for x86 successfully is to generate correct standalone tool chains for x86 based on the Android NDK. This method will be useful for not only ZeroMQ, but also for other 3rd party library builds.

References

ØMQ - http://en.wikipedia.org/wiki/%C3%98MQ ZeroMQ build for Android - http://zeromq.org/build:android ØMQ - The Guide - http://zguide.zeromq.org/page:all

About the Author

Bin Zhu is an application engineer in the Intel® Atom™ Processor Mobile Enabling Team, Developer Relations Division, Software and Solutions Group (SSG). He is responsible for Android app enabling on Intel Atom processors and focuses on multimedia technologies for the Android x86 platforms.