Cross-compile ITK’s Python Wrapping for the Raspberry Pi 2
This post describes how to cross-compile the Insight Toolkit (ITK)'s Python wrapping for the Raspberry Pi 2. The default operating system on the Raspberry Pi 2 is Raspbian, a Debian-based Linux distribution. While Debian provides packages for ITK., these packages are not currently available on Raspbian. We will create a Debian package optimized for the Raspberry Pi 2 that can be installed and uninstalled on our Pi. The process is similar to the previous post on cross-compiling for the Raspberry Pi, with the following additions:
- Optimization flags specific to the Raspberry Pi 2.
- Build wrapping against the Raspbian Python installation.
- Create a Debian package.
Let's go!
Image credit: the PyScience blog
Get the cross-compiler
If Docker is installed, download the cross-compiler image. This cross-compiler with work with both the Raspberry Pi and the Raspberry Pi 2, even though Raspberry Pi is ARMv7.
docker pull thewtex/cross-compiler-linux-armv6
Get the code
Download the ITK source tree if it not already available, and create a build directory:
cd ~/src git clone http://itk.org/ITK.git mkdir -p ~/bin/ITK-build
We also need the Python headers and library from the Pi so we can compile and link against them. We will log into the Pi, create a tarball of the needed files and directories, and transfer that tarball to the build host.
ssh pi@raspberrypi sudo apt-get install python-dev tar cvzf raspbian-python.tar.gz \ /usr/include/python2.7 \ /usr/lib/python2.7 \ /usr/lib/libpython2.7.* exit scp pi@raspberrypi:raspbian-python.tar.gz /tmp/ mkdir -p ~/bin/raspbian-python tar xvzf /tmp/raspbian-python.tar.gz -C ~/bin/raspbian-python/
Build and package
Start up the docker container, and mount the source directory, build directory, and Python filesystem directory as volumes in the container:
docker run --rm -it \ -v ~/src/ITK:/usr/src/ITK:ro \ -v ~/bin/ITK-build:/usr/src/ITK-build:rw \ -v ~/bin/raspbian-python:/usr/src/raspbian-python:ro \ thewtex/cross-compiler-linux-armv6
Next, clear the build tree and configure the build:
cd /usr/src/ITK-build rm -rf * export flags='-mfpu=neon-vfpv4 -mcpu=cortex-a7 -mfloat-abi=hard' cmake \ -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} \ -DBUILD_EXAMPLES=OFF \ -DBUILD_TESTING=OFF \ -DITK_WRAP_PYTHON=ON \ -DPYTHON_LIBRARY=/usr/src/raspbian-python/usr/lib/libpython2.7.so.1 \ -DPYTHON_INCLUDE_DIR=/usr/src/raspbian-python/usr/include/python2.7/ \ -DPY_SITE_PACKAGES_PATH=lib/python2.7/dist-packages \ -DCMAKE_CXX_FLAGS="${flags}" \ -DCMAKE_C_FLAGS="${flags}" \ -DCMAKE_CXX_COMPILER_TARGET=${CROSS_TRIPLE} \ -DCMAKE_INSTALL_PREFIX=/usr/ \ -DCPACK_DEBIAN_PACKAGE_NAME=libinsighttoolkit4.8 \ -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=armhf \ -G Ninja \ ../ITK
The CMAKE_TOOLCHAIN_FILE option informs CMake about the build toolchain. BUILD_EXAMPLES, BUILD_TESTING, and ITK_WRAP_PYTHON are options for ITK. PYTHON_LIBRARY and PYTHON_INCLUDE_DIR inform CMake of the Python we want to build against. PY_SITE_PACKAGES_PATH tells CMake where to install the Python package. The value used, lib/python2.7/dist-packages, is obtained by running the following command on the Pi:
python -c "from distutils.sysconfig import get_python_lib;print(get_python_lib(1, prefix=''))"
Optimization flags to use features available on the Raspberry Pi 2 processor are passed with the CMAKE_C_FLAGS and CMAKE_CXX_FLAGS options. The cross-compiling target triple, used by the wrapping system, is passed via the CMAKE_CXX_COMPILER_TARGET through the value of the CROSS_TRIPLE enviromental variable. CMAKE_INSTALL_PREFIX, CPACK_DEBIAN_PACKAGE_NAME, and CPACK_DEBIAN_PACKAGE_ARCHITECTURE are options for creating the Debian package. We also tell CMake to use our favorite generator, Ninja.
Build the library:
ninja
Build the package:
cpack -G DEB
This generates a .deb package. Copy it to the Pi:
scp ITK-4.8.0-Linux.deb pi@raspberrypi:
And install it:
ssh pi@raspberrypi sudo dpkg -i ITK-4.8.0-Linux.deb
Start up Python, and import the itk package:
python >>> import itk
Enjoy ITK!