Building wheels#

Because setuptools-rust is an extension to setuptools, the standard python -m build command (or pip wheel --no-deps . --wheel-dir dist) can be used to build distributable wheels. These wheels can be uploaded to PyPI using standard tools such as twine.

A key choice to make is whether to upload PEP 384 “stable” (aka “limited”) API wheels which support multiple Python versions in a single binary, or to build individual artifacts for each Python version. There is a longer discussion of this in the PyO3 docs.

This chapter covers each of these options below.

Building for ABI3#

setuptools-rust will automatically configure for the limited API when this is set in the [bdist_wheel] configuration section of setup.cfg:

[bdist_wheel]
py_limited_api=cp37  # replace with desired minimum Python version

If using a pyproject.toml-based build, then save the above in a file and use the DIST_EXTRA_CONFIG environment variable to instruct setuptools to pick up this extra configuration. (DIST_EXTRA_CONFIG is documented on this page of the setuptools docs.)

It is also possible to pass this setting via the command line, e.g.

python -m build --config-settings=--build-option=--py-limited-api=cp37

Building for multiple Python versions#

Using cibuildwheel#

cibuildwheel is a tool to build wheels for multiple platforms using Github Actions.

The rtoml package does this, for example.

Building manually#

Place a script called build-wheels.sh with the following contents in your project root (next to the setup.py file):

#!/bin/bash
set -ex

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
export PATH="$HOME/.cargo/bin:$PATH"

# Compile wheels
for PYBIN in /opt/python/cp{37,38,39,310}*/bin; do
    rm -rf /io/build/
    "${PYBIN}/pip" install -U setuptools setuptools-rust wheel
    "${PYBIN}/pip" wheel /io/ -w /io/dist/ --no-deps
done

# Bundle external shared libraries into the wheels
for whl in /io/dist/*{cp37,cp38,cp39,cp310}*.whl; do
    auditwheel repair "$whl" -w /io/dist/
done

# Install packages and test
for PYBIN in /opt/python/cp{37,38,39,310}*/bin; do
    "${PYBIN}/pip" install html-py-ever -f /io/dist/
done

This script can be used to produce wheels for multiple Python versions.

Binary wheels on linux#

To build binary wheels on linux, you need to use the manylinux docker container. You will run the build-wheels.sh from above inside that container.

First, pull the manylinux2014 Docker image:

docker pull quay.io/pypa/manylinux2014_x86_64

Then use the following command to build wheels for supported Python versions:

docker run --rm -v `pwd`:/io quay.io/pypa/manylinux2014_x86_64 bash /io/build-wheels.sh

This will create wheels in the dist directory:

$ ls dist
hello_rust-0.1.0-cp37-cp37m-linux_x86_64.whl          hello_rust-0.1.0-cp37-cp37m-manylinux2014_x86_64.whl
hello_rust-0.1.0-cp38-cp38-linux_x86_64.whl           hello_rust-0.1.0-cp38-cp38-manylinux2014_x86_64.whl
hello_rust-0.1.0-cp39-cp39-linux_x86_64.whl           hello_rust-0.1.0-cp39-cp39-manylinux2014_x86_64.whl

It is possible to use any of the manylinux docker images: manylinux1, manylinux2010 or manylinux2014. (Just replace manylinux2014 in the above instructions with the alternative version you wish to use.)

Binary wheels on macOS#

For building wheels on macOS it is sufficient to use one of the default python -m build or pip wheel --no-deps . --wheel-dir dist commands.

To build universal2 wheels set the ARCHFLAGS environment variable to contain both x86_64 and arm64, for example ARCHFLAGS="-arch x86_64 -arch arm64". Wheel-building solutions such as cibuildwheel set this environment variable automatically.