cibuildwheel#

cibuildwheel simplifies the creation of Python Wheels for the different platforms and Python versions through Continuous Integration (CI) workflows. More precisely it builds manylinux, macOS 10.9+, and Windows wheels for CPython and PyPy with GitHub Actions, Azure Pipelines, Travis CI, AppVeyor, CircleCI, or GitLab CI/CD.

In addition, it bundles shared library dependencies on Linux and macOS through auditwheel and delocate.

Finally, the tests can also run against the wheels.

See also

GitHub Actions#

To build Linux, macOS, and Windows wheels, create a .github/workflows/build_wheels.yml file in your GitHub repo:

name: Build

on:
  workflow_dispatch:
  release:
    types:
      - published
workflow_dispatch

allows you to click a button in the graphical user interface to trigger a build. This is perfect for manually testing wheels before a release, as you can easily download them from artifacts.

release

is executed when a tagged version is transferred.

See also

Now the wheels can be built with:

jobs:
  build_wheels:
    name: Build wheels on ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-20.04, windows-2019, macos-11]

    steps:
      - uses: actions/checkout@v3

      - name: Build wheels
        uses: pypa/cibuildwheel@v2.15.0

This runs the CI workflow with the following default settings:

  • package-dir: .

  • output-dir: wheelhouse

  • config-file: "{package}/pyproject.toml"

You can also extend the file to automatically upload the wheels to the Python Package Index (PyPI). For this, however, you should first create a source distribution, for example with:

  make_sdist:
    name: Make SDist
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
      with:
        fetch-depth: 0  # Optional, use if you use setuptools_scm
        submodules: true  # Optional, use if you have submodules

    - name: Build SDist
      run: pipx run build --sdist

    - uses: actions/upload-artifact@v3
      with:
        path: dist/*.tar.gz

In addition, this GitHub workflow must be set in the PyPI settings of your project:

Now you can finally upload the artefacts of both jobs to the PyPI:

  upload_all:
    needs: [build_wheels, make_sdist]
    environment: pypi
    permissions:
      id-token: write
    runs-on: ubuntu-latest
    if: github.event_name == 'release' && github.event.action == 'published'
    steps:
    - uses: actions/download-artifact@v3
      with:
        name: artifact
        path: dist

    - uses: pypa/gh-action-pypi-publish@release/v1

GitLab CI/CD#

To build Linux wheels with GitLab CI/CD, create a .gitlab-ci.yml file in your repository:

linux:
  image: python:3.8
  # make a docker daemon available for cibuildwheel to use
  services:
    - name: docker:dind
      entrypoint: ["env", "-u", "DOCKER_HOST"]
      command: ["dockerd-entrypoint.sh"]
  variables:
    DOCKER_HOST: tcp://docker:2375/
    DOCKER_DRIVER: overlay2
    # See https://github.com/docker-library/docker/pull/166
    DOCKER_TLS_CERTDIR: ""
  script:
    - curl -sSL https://get.docker.com/ | sh
    - python -m pip install cibuildwheel==2.15.0
    - cibuildwheel --output-dir wheelhouse
  artifacts:
    paths:
      - wheelhouse/

windows:
  image: mcr.microsoft.com/windows/servercore:1809
  before_script:
    - choco install python -y --version 3.8.6
    - choco install git.install -y
    - py -m pip install cibuildwheel==2.15.0
  script:
    - py -m cibuildwheel --output-dir wheelhouse --platform windows
  artifacts:
    paths:
      - wheelhouse/
  tags:
    - windows

Optionen#

cibuildwheel can be configured either via environment variables or via a configuration file such as pyproject.toml, for example:

[tool.cibuildwheel]
test-requires = "pytest"
test-command = "pytest {project}/tests"
build-verbosity = 1

# support Universal2 for Apple Silicon:
[tool.cibuildwheel.macos]
archs = ["auto", "universal2"]
test-skip = ["*universal2:arm64"]

Examples#