Search code examples
androidpython-2.7scikit-learnkivybuildozer

Building Python packages succeeds, but Scikit-learn is improperly built


I created an app using Scikit-learn and Kivy and it was built with Buildozer.

This is the code of main.py :

# coding=utf-8

import kivy
import sys
kivy.require('1.9.0')

from kivy.app import App
from kivy.uix.label import Label

class MyApp(App):

    def build(self):
        try:
            from sklearn import svm, datasets
        except:
            return Label(text=str(sys.exc_info()[1]))
        else:
            return Label(text='Scikit-learn OK')

if __name__ == '__main__':
    MyApp().run()

I specified Scikit-learn in the requirements in buildozer.spec :

[app]

title = Kivyris

package.name = kivyris

package.domain = org.test

source.dir = .

source.include_exts = py,png,jpg,kv,atlas

version = 0.1

requirements = kivy,numpy,scipy,scikit-learn

orientation = landscape

fullscreen = 1

log_level = 2

warn_on_root = 1

I ran buildozer android_new debug deploy run (no error, APK file created and deployed) but I have the following error when the app is launched :

Cannot load library:


Contents of /data/data/org.test.kivyris/files/app/lib/python2.7/site-packages/sklearn/check_build: __init.pyo setup.pyo _check_build.so


It seems that sckikit-learn has not been built correctly.

If you have installed scikit-learn from source, please do not forget to build the package before using it; run python setup.py install or make in the source directory.

If you have used an installer, please check that it is suited for your Python version, your operating system and your platform.

On Windows and Ubuntu using python main.py it works well :

Scikit-Learn OK

I installed Scikit-learn using sudo apt-get install python-scikits-learn on Ubuntu 16.04 LTS. This is some informations from the device on which I ran the app :

  • import platform failed; platform.platform() : I couldn't get this info (app failed to launch), but it's an Android 5.1.1
  • import sys OK; sys.version : 2.7.2 (default, Mar 6 2017, 06:05:36) [GCC 4.8]
  • import numpy OK; Numpy.version : 1.9.2
  • import scipy OK; Scipy.version : 0.18.1
  • import sklearn : error (see above).

I tried a few things unsuccessfully, so I looked online :

I didn't find anything useful and I have no idea how to solve that. Any idea please ?

Thank you.


Solution

  • When you're trying to build your app for Android with module that uses pure Python, everything is ok: this module would be run by Python interpreter built for Android and shipped with your app.

    Things much worse when your trying to build app for Android with module contains C extension or dependencies with C extensions (such as Scikit-learn). On Windows or Linux C Extensions would be compiled using distutils, but for Android it's problem: C Extensions can't be compiled this way.

    python-for-android handles this problem providing mechanism of recipes:

    recipe: A recipe is a file that defines how to compile a requirement. Any libraries that have a Python extension must have a recipe in p4a, or compilation will fail. If there is no recipe for a requirement, it will be downloaded using pip.

    You can see list of existing recipes here. As you can see no one did one for Scikit-learn, so I assume it can't be build for Android right now.

    You can try to create recipe for this module manually or ask someone to help in kivy Google group. Note, that it's probably not trivial task.