How to setup Python crossenv for macOS-iOS cross compilation

How to setup Python crossenv for macOS-iOS cross compilation

Warning: Cross compilation is often hardâ„¢, having a crossenv makes things easier but it’s not magic. For example numpy needs lapack and blas, which need fortran. Scipy needs fortran and numpy. But there is no working fortran compiler for iOS.

Python crossenv is a special venv (virtual environment) for cross compiling python packages. The two main concepts are:

build-python: In our case this is the macOS python.

host-python: This is the python interpreter compiled for iOS.

To avoid obscure errors we should use the exact same python version for build-python and host-python. Fortunately beeware has already automated the patching and building of cpython for iOS and macOS. I will use cpython 3.8 but it should work with newer versions. Apparently there was a lot of cross compilation improvements in cpython 3.5.

# This will be our working directory
mkdir ~/Python-Crossenv
cd ~/Python-Crossenv

git clone -b 3.8 https://github.com/beeware/Python-Apple-support.git
cd Python-Apple-Support	
make all

The resulting macOS cpython will be in:

build/macOS/Python-3.8.13-macOS/_install/

While the resulting iOS cpython will be in:

build/iOS/Python-3.8.13-iphonesimulator.x86_64/_install/

Note that in this example I’m using the x86_64 simulator.

Now we need to install the macOS cpython. On unix machines prefer to install custom software under /usr/local/stow then use GNU Stow to link it to /usr/local. This makes uninstalling a breeze.

sudo cp -rf build/macOS/Python-3.8.13-macOS/_install/ \
/usr/local/stow/Python3.8-macOS

# We only need to install the macOS version but lets copy
# both for convenience
sudo cp -rf build/iOS/Python-3.8.13-iphonesimulator.x86_64/_install/ \
/usr/local/stow/Python3.8-iOS

cd /usr/local/stow
# Remember only macOS
sudo stow Python3.8-macOS

Pip doesn’t work on iOS and thus is disabled on both builds. Fortunately installing it is very easy.

cd ~/Python-Crossenv
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
/usr/local/bin/python3.8 ./get-pip.py

Now we can pretty much follow the python-crossenv docs.

# Install crossenv
/usr/local/python3.8 -m pip install crossenv

# Create a new crossenv
/usr/local/bin/python3.8 -m crossenv \
/usr/local/stow/Python3.8-iOS \
cross_env

source cross_env/bin/activate

Now you “only” need to run pip install package. I put “only” in quotation marks because in all likelihood you will need to patch whatever you are trying to build. Note that some packages are required at build time and those should be installed with build-pip.

This is it. You can now start your cross compilation journey.