Kodi for Android: Building and Using Binary Python Extensions - Part 1

 Nov. 12, 2016     0 comments

Important WARNING!

On recent Android 7 firmwares for some devices, including my Samsung Galaxy Tab A 10.1, the magic workaround that allows to load binary Python modules from Kodi addons no longer works. This means that currently there is no known way to import binary modules in Python addons on such devices. Because of this the following series of articles now has only historical value since there is a strong chance that you won't be able to use your compiled binary Python module(s).

This is the 1st article in my series about building and using binary Python modules in Kodi on Android. In this article I will cover prerequisites needed to build a Python/C extension module for Python in Kodi for Android.


1. CrystaX NDK

Android NDK is a set of tools that allow to build binary (native) components for Android apps. We will use CrystaX NDK. The guys that have developed CrystaX NDK describe it as a drop-in replacement for Google's Android NDK but with better support of C/C++ standards. And that's exactly what we need. Download CrystaX NDK for you platform and unpack it to the directory of your choice. In my experiments it's located in d:\crystax-ndk-10.3.2 directory on a Windows machine.

2. Python headers

First, we need to decide which Python version we will use to build our binary modules. Before v. 17 (Krypton) Kodi on Android used Python 2.6 but starting from v. 17 all platforms use Python 2.7, including Android. Unfortunately, newer Kodi versions are released for newer Android versions. However there are still many devices in use that have been abandoned by their manufacturers and do not receive OS updates. So those devices are stuck with older Kodi versions. For example, my Acer IconiaTab A510 tablet stull runs Android 4.1 JB so the maximum Kodi version I can use is 14.2 (Helix). So the rule is simple: if you are not going to support Kodi versions older than 17 (Krypton), choose Python 2.7. Otherwise you will have to use Python 2.6. Just to be clear: Python/C API does not have backward-incompatible changes, so binary modules built against Python 2.6 will work on 2.7 too. (This statement is not true in case of Python 2 vs 3, but for Kodi addons it is not relevant.)

CrystaX NDK v.10.3.2 already include Python 2.7 headers so you can use those. If you choose Python 2.6, download Python sources from GitHub (don't forget to check-out the necessary version) or from Kodi mirrors. We need only Include directory that contains necessary C headers. Put those in the directory on your choice. However, raw Python sources are missing configuration headers that define interpreter configuration for a specific platform. Fortunately, CrystaX NDK has those headers so we can borrow them. Go to d:\crystax-ndk-10.3.2\sources\python\2.7\include\python directory (adjust the path to your specific location) and copy all header files that start with pyconfig* to other Python headers. If you are using Python 2.7 headers from CrystaX NDK I'd recommend to copy all headers to a separate directory.

Now open the file pyconfig.h in your favorite code editor and add the following lines to the end of the file:

#define Py_UNICODE_SIZE 2

Python in CrystaX NDK uses 4 byte Unicode characters while Python in Kodi is built with 2 byte Unicode characters, so without those strings your binary module may fail to build.

3. The libkodi.so library

Unlike other platforms, Kodi for Android is built as one big (~40MB) shared library that includes almost everything, including Python interpreter (meaning Python symbols needed for linking). Usually, binary Python modules are linked against a Python library (shared or static) but in our case we need to link against this big Kodi library called libkodi.so.

To obtain this library download a Kodi .apk package from the official Kodi site. If you are going to build against Python 2.7, download Kodi 17 (Krypton) or above, otherwise download a Kodi 16 (Jarvis) .apk. Open the .apk with 7zip archiver, then find and extract libkodi.so file into a directory of your choice.

Note on SPMC: SPMC is a fork of Kodi for Android made by the same guy who brought Kodi to Android. If you want to support SPMC you need to build a separate version of your binary module that is linked against libspmc.so library. This library can be extracted from a SPMC .apk. the same way as described above.

In the 2nd article I will tell you how to build a simple Python/C binary module for Python in Kodi on Android.