This directory contains the build-wheel tool, which produces Android .whl files compatible with Chaquopy.
build-wheel can build .whl files for all Android ABIs (armeabi-v7a, arm64-v8a, x86 and x86_64). However, the tool itself only runs on Linux x86-64. If you don't already have a Linux machine available, a cheap virtual server from somewhere like DigitalOcean will do just fine.
First, clone this repository.
Then, go to this Maven Central
page and select which
Python version you want to build for. Within a given Python minor version (e.g. 3.8),
you should usually use the newest version available. Then use download-target.sh to
download it into maven in the root of this repository. For example, to download
version 3.8.16-0, run:
target/download-target.sh maven/com/chaquo/python/target/3.8.16-0
You'll also need a matching version of Python installed on your build machine. For
example, if you're building for Python 3.8, then python3.8 must be on the PATH. You may
be able to get this from your distribution, or from an unofficial package repository.
Otherwise, here's how to install it with Miniconda:
- Download the installer from https://docs.conda.io/en/latest/miniconda.html.
- To work around conda/conda#10431, run it like this:
bash Miniconda3-latest-Linux-x86_64.sh. - When asked whether to run
conda init, answer yes, and follow the instructions.
- To work around conda/conda#10431, run it like this:
conda create -n build-wheel python=X.Y, whereX.Yis the Python version you want to build for.conda activate build-wheel
Export the ANDROID_HOME environment variable to point at your Android SDK. If you don't
already have the SDK, here's how to install it:
- Download the "Command line tools" from https://developer.android.com/studio.
- Create a directory
android-sdk/cmdline-tools, and unzip the command line tools package into it. - Rename
android-sdk/cmdline-tools/cmdline-toolstoandroid-sdk/cmdline-tools/latest. export ANDROID_HOME=/path/to/android-sdk
Use pip to install the requirements.txt in this directory.
Use your distribution's package manager to install the following build tools:
- patch
- patchelf
Depending on which package you're building, you may also need additional tools. Most of
these can be installed using your distribution. Some of them have special entries in the
build requirements section of meta.yaml:
fortran: You must install the Fortran compiler from here. Create afortransubdirectory in the same directory as this README, and unpack the .bz2 files into it.rust:rustupmust be on the PATH.
Run build-wheel from this directory as follows:
./build-wheel.py --python X.Y --abi ABI PACKAGE
Where:
X.Yis the Python version you set up above, e.g.3.8.ABIis an Android ABI.PACKAGEis a subdirectory ofpackagesin this directory, or the path to another directory laid out in the same way (see "adding a package" below).
The resulting .whl files will be generated in the dist subdirectory of this directory.
Under packages in this directory, create a recipe directory named after the package,
normalized according to PEP
503. Alternatively, you can create
this directory somewhere else, and pass its path when calling build-wheel.
Inside the recipe directory, add the following files:
- A
meta.yamlfile. This supports a subset of Conda syntax, defined inmeta-schema.yaml. - For non-Python packages, a
build.shscript. - If necessary, a
patchessubdirectory containing patch files.
Here are some examples of existing recipes:
- multidict: a minimal example, downloaded from PyPI.
- cython-example: a minimal example, built from a local directory.
- python-example: a pybind11-based package, downloaded from a Git repository.
- cmake-example: similar to python-example, but uses CMake.
- chaquopy-libzmq: a non-Python library, downloaded from a URL.
- pyzmq: a Python package which depends on chaquopy-libzmq. A patch is used to help
setup.pyfind the library. - scikit-learn: lists several requirements in
meta.yaml:- The "build" requirement (Cython) will be installed automatically.
- The "host" requirements (NumPy etc.) must be downloaded manually from the public
repository. Save them into a corresponding
subdirectory of
dist(e.g.dist/numpy), before running the build.
Then run build-wheel as shown above.
If any changes are needed to make the build work, the easiest procedure is:
- In the recipe directory, enter the
buildsubdirectory and locate the package's source code. - Edit the source code as necessary.
- Re-run build-wheel with the
--no-unpackoption to prevent your changes from being overwritten. - Once everything's working, save your changes in a patch file in the recipe's
patchessubdirectory. This will be applied automatically in any future builds.
.whl files can be built into your app using the pip
block in your
build.gradle file. First, add an options line to pass
--extra-index-url
with the location of the dist directory mentioned above. Either an HTTP URL or a local path
can be used. Then add an install line giving the name of your package.
The pkgtest app in this directory is a test harness for checking package builds. Here's how to use it.
First, create a test.py file in the recipe directory, or a test subdirectory with an
__init__.py if you need to include additional files. This should contain a TestCase
class which does some basic checks on the package. See the existing recipes for
examples: usually we base them on the package's own tutorial.
Open the pkgtest app in Android Studio, and temporarily edit app/build.gradle as
follows:
- Set
PACKAGESto the package's name. - Set
python { version }to the Python version you want to test. - Set the
--extra-index-urlas described above. - Set
abiFiltersto the ABIs you want to test.
Then run the app.