hypernephelist n. [from Greek nepho-, cloud] someone who goes above the clouds.

Compiling the Qpid Proton Python bindings for the Arduino Yun

In a previous post, I cross-compiled the Apache Qpid Proton C library for the Arduino Yun. However, I also wanted to be able to use the Python bindings on the Yun, so that I can write a simple script to run via the Bridge library, instead of a C program that people would need to cross-compile. The build process published by MS Open Tech China does not include the Python bindings, but here are some instructions to add them.

Cross-compiling Python

First, we need to add the Python package to our OpenWRT toolchain so that we have the right includes files and libraries. Just add python as a dependency in the OpenWRT Makefile for Proton:

vi package/openwrt-qpid-proton/Makefile

Add the dependency like so:

DEPENDS:=+libopenssl +libuuid python

We will also add a few lines to this same Makefile to install the Python bindings; in the install section add the following:

$(INSTALL_DIR) $(1)/usr/lib/proton
$(INSTALL_BIN) $(PKG_BUILD_DIR)/proton-c/bindings/python/cproton.py $(1)/usr/lib/proton
$(INSTALL_BIN) $(PKG_BUILD_DIR)/proton-c/bindings/python/_cproton.so $(1)/usr/lib/proton
$(INSTALL_BIN) $(PKG_BUILD_DIR)/proton-c/bindings/python/proton.py $(1)/usr/lib/proton

Then rebuild everything:

make V=s

In my case I encountered some problems when compiling the gdbm dependency, specifically this error:

using a Makefile.in.in from gettext version 0.18 but the autoconf macros are from gettext version 0.19

Then you should edit the culprit:

vi build_dir/target-mips_34kc_uClibc-0.9.33.2/gdbm-1.11/po/Makefile.in.in

And change the version of the aforementioned variable:

GETTEXT_MACRO_VERSION = 0.19

Re-run make V=s to complete the build.

Now you should have a brand new Python interpreter compiled in the following directory:

build_dir/target-mips_34kc_uClibc-0.9.33.2/Python-2.7.9/ipkg-install

We need to copy at least the include files and library files to the toolchain directory:

export ST=staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2
export BD=build_dir/target-mips_34kc_uClibc-0.9.33.2
mkdir $ST/include/python2.7
cp $BD/Python-2.7.9/ipkg-install/usr/include/python2.7/* $ST/include/python2.7
cp -r $BD/Python-2.7.9/ipkg-install/usr/lib/* $ST/lib

Generating the Python bindings

Now you need to install SWIG on the host so that it can generate the Python bindings:

sudo apt-get install swig2.0

Then rebuild the openwrt-qpid-proton package. It should find SWIG and setup the project to build the Python bindings.

make V=s package/openwrt-qpid-proton/clean
make V=s package/openwrt-qpid-proton/compile

Here I got errors when compiling the binding source generated by SWIG… Something like this:

cprotonPYTHON_wrap.c:3540: undefined reference to `__finite'

I had to edit the SWIG source to undefine a symbol and overcome the undefined reference:

vi build_dir/target-mips_34kc_uClibc-0.9.33.2/openwrt-qpid-proton-0.8/proton-c/bindings/python/cprotonPYTHON_wrap.c

Line 3527, add:

#undef SWIG_isfinite

Now everything should compile! The ipkg will be regenerated and will include the Python bindings.

Missing libpython2.7.so

For some reason, the Python package for the Yun version of OpenWRT is compiled with --disable-shared, while the stock one from the original OpenWRT repository is configured with --enable-shared. This means simply that libpython2.7.so is not available on the Yun. This breaks the SWIG-generated module for Proton. I haven’t found a clean solution, so I just copied the shared library from my OpenWRT build to /usr/lib on the Yun.

I will post a simpler TL;DR post on how to just install and use Proton from Python on the Yun!

In the meantime, here are the compiled packages ready to download: