Compiling the Qpid Proton Python bindings for the Arduino Yun
07 Apr 2015In 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: