diff --git a/docs/ext/cibuildwheel.py b/docs/ext/cibuildwheel.py index 8373401f8..043cc0b23 100644 --- a/docs/ext/cibuildwheel.py +++ b/docs/ext/cibuildwheel.py @@ -2,21 +2,103 @@ Binary wheels table extension for Sphinx. This extension parses a GitHub Actions workflow for building binary wheels, and -summarizes it in a stylish table. +summarizes the build onfiguration in a stylish table. """ -from docutils import nodes -from sphinx.util.docutils import SphinxDirective +import itertools +import pathlib +import sphinx.util.docutils +import yaml -class WheelsDirective(SphinxDirective): - """A directive to say hello!""" +FALCON_ROOT = pathlib.Path(__file__).resolve().parent.parent.parent + +_CHECKBOX = '\u2705' +_CPYTHON_PLATFORMS = { + 'manylinux_x86_64': '**Linux Intel** ``manylinux`` 64-bit', + 'musllinux_x86_64': '**Linux Intel** ``musllinux`` 64-bit', + 'manylinux_i686': '**Linux Intel** ``manylinux`` 32-bit', + 'musllinux_i686': '**Linux Intel** ``musllinux`` 32-bit', + 'manylinux_aarch64': '**Linux ARM** ``manylinux`` 64-bit', + 'musllinux_aarch64': '**Linux ARM** ``musllinux`` 64-bit', + 'manylinux_ppc64le': '**Linux PowerPC** ``manylinux`` 64-bit', + 'musllinux_ppc64le': '**Linux PowerPC** ``musllinux`` 64-bit', + 'manylinux_s390x': '**Linux IBM Z** ``manylinux``', + 'musllinux_s390x': '**Linux IBM Z** ``musllinux``', + 'macosx_x86_64': '**macOS Intel**', + 'macosx_arm64': '**macOS Apple Silicon**', + 'win32': '**Windows** 32-bit', + 'win_amd64': '**Windows** 64-bit', + 'win_arm64': '**Windows ARM** 64-bit', +} + + +class WheelsDirective(sphinx.util.docutils.SphinxDirective): + """Directive to tabulate build info from a YAML workflow.""" required_arguments = 1 + @classmethod + def _emit_table(cls, data): + columns = len(data[0]) + assert all( + len(row) == columns for row in data + ), 'All rows must have the same number of columns' + + width = max(len(cell) for cell in itertools.chain(*data)) + # Leave padding to cell borders + width += 2 + + hline = ('+' + '-' * width) * columns + '+\n' + output = [hline] + header_line = True + + for row in data: + for cell in row: + # NOTE(vytas): Emojis take two spaces... + padded_width = width - 1 if cell == _CHECKBOX else width + output.append('|') + output.append(cell.center(padded_width)) + + output.append('|\n') + + if header_line: + output.append(hline.replace('-', '=')) + header_line = False + else: + output.append(hline) + + return ''.join(output) + def run(self): - paragraph_node = nodes.paragraph(text=f'hello {self.arguments[0]}!') - return [paragraph_node] + workflow_path = pathlib.Path(self.arguments[0]) + if not workflow_path.is_absolute(): + workflow_path = FALCON_ROOT / workflow_path + with open(workflow_path) as fp: + workflow = yaml.safe_load(fp) + + matrix = workflow['jobs']['build-wheels']['strategy']['matrix'] + include = matrix['include'] + assert not matrix.get('exclude'), 'TODO: exclude is not supported yet' + + supported = set( + itertools.product( + [platform['name'] for platform in matrix['platform']], matrix['python'] + ) + ) + supported.update((item['platform']['name'], item['python']) for item in include) + + table = [ + ('Platform / CPython version', '3.8', '3.9', '3.10', '3.11', '3.12', '3.13') + ] + for name, description in _CPYTHON_PLATFORMS.items(): + row = [description] + for cpython in ('cp38', 'cp39', 'cp310', 'cp311', 'cp312', 'cp313'): + value = _CHECKBOX if (name, cpython) in supported else '' + row.append(value) + table.append(row) + + return self.parse_text_to_nodes(self._emit_table(table)) def setup(app): diff --git a/docs/user/install.rst b/docs/user/install.rst index c90f4a9af..d7838d259 100644 --- a/docs/user/install.rst +++ b/docs/user/install.rst @@ -39,9 +39,13 @@ Or, to install the latest beta or release candidate, if any: In order to provide an extra speed boost, Falcon can compile itself with Cython. Wheels containing pre-compiled binaries are available from PyPI for -several common platforms. However, if a wheel for your platform of choice is not -available, you can choose to stick with the source distribution, or use the -instructions below to cythonize Falcon for your environment. +several common platforms (see :ref:`binary_wheels` below for the complete list +of the platforms that we target, or simply check +`Falcon files on PyPI `__). + +However, even if a wheel for your platform of choice is not available, you can +choose to stick with the source distribution, or use the instructions below to +cythonize Falcon for your environment. The following commands tell pip to install Cython, and then to invoke Falcon's ``setup.py``, which will in turn detect the presence of Cython @@ -64,7 +68,8 @@ pass `-v` to pip in order to echo the compilation commands: $ pip install -v --no-build-isolation --no-binary :all: falcon -**Installing on OS X** +Installing on OS X +^^^^^^^^^^^^^^^^^^ Xcode Command Line Tools are required to compile Cython. Install them with this command: @@ -87,12 +92,27 @@ these issues by setting additional Clang C compiler flags as follows: $ export CFLAGS="-Qunused-arguments -Wno-unused-function" +.. _binary_wheels: + Binary Wheels -------------- +^^^^^^^^^^^^^ + +Binary Falcon wheels for are automatically built for many CPython platforms, +courtesy of `cibuildwheel `__. -Tell the story about CIBW... +The following table summarizes the wheel availability on different combinations +of CPython versions vs CPython platforms: + +.. wheels:: .github/workflows/cibuildwheel.yaml + +.. note:: + The `free-threaded build + `__ + mode is not enabled for our wheels at this time. -.. wheels:: .github/workflows/cibuildwheel +While we believe that the above configuration covers the most common +development and deployment scenarios, :ref:`let us known ` if you are +interested in any builds that are currently missing from our selection! Dependencies ------------