Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ build --incompatible_default_to_explicit_init_py
build --cxxopt=-std=c++20
build --host_cxxopt=-std=c++20

# =============================================================================
# Python Stable ABI (nanobind)
# =============================================================================
# Build the nanobind extension against CPython's stable ABI (abi3), floored at
# 3.12. A single `cp312-abi3` extension then runs on every CPython >= 3.12, so
# dev/test builds here exercise the exact artifact shipped in the wheel. The
# wheel target re-pins this via its Starlark transition so the artifact is
# correct even in a host workspace whose .bazelrc lacks this flag.
build --@nanobind_bazel//:py-limited-api=cp312

# =============================================================================
# Release Config (opt + strip)
# =============================================================================
Expand Down
47 changes: 11 additions & 36 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -358,9 +358,10 @@ jobs:
package-dir: .
output-dir: artifacts/wheels
env:
# cp310 has no official Windows ARM64 CPython; cibuildwheel skips it
# there automatically, so the same build set is safe for both arches.
CIBW_BUILD: "cp310-* cp311-* cp312-* cp313-* cp314-*"
# A single stable-ABI (abi3) build on CPython 3.12 produces one
# cp312-abi3 wheel that runs on every CPython >= 3.12 (meson.build sets
# limited_api = '3.12').
CIBW_BUILD: "cp312-*"
CIBW_ARCHS_WINDOWS: ${{ matrix.cibw_arch }}
CIBW_BUILD_VERBOSITY: "1"
# Force MSVC. The windows-2022/windows-11-arm images ship MinGW GCC
Expand Down Expand Up @@ -533,30 +534,8 @@ jobs:
cp package/Dockerfile package/deb_smoke.cpp smoke_ctx/
cp debs/*.deb smoke_ctx/
ls -l smoke_ctx
# Retry the build: the arm64 image installs deps from ports.ubuntu.com,
# which intermittently times out from the CI network. --no-cache on
# retries forces a fresh apt-get update instead of reusing a failed
# layer.
attempts=3
for attempt in $(seq 1 "${attempts}"); do
echo "::group::docker build (attempt ${attempt}/${attempts})"
cache_flag=""
if [[ "${attempt}" -gt 1 ]]; then
cache_flag="--no-cache"
fi
if docker build ${cache_flag} --platform ${{ matrix.docker_platform }} \
-t fastslide-deb-smoke smoke_ctx; then
echo "::endgroup::"
exit 0
fi
echo "::endgroup::"
echo "docker build failed on attempt ${attempt}/${attempts}"
if [[ "${attempt}" -lt "${attempts}" ]]; then
sleep $((attempt * 15))
fi
done
echo "docker build failed after ${attempts} attempts" >&2
exit 1
docker build --platform ${{ matrix.docker_platform }} \
-t fastslide-deb-smoke smoke_ctx
# TEMPORARILY DISABLED: the source build pulls simpletiff from its pinned git
# wrap (subprojects/simpletiff.wrap @ 3886522), which predates the
# <cstdio>-before-<jpeglib.h> fix and so fails to compile under GCC. Re-enable
Expand Down Expand Up @@ -586,8 +565,8 @@ jobs:
# shell: bash
# run: |
# set -euo pipefail
# uv python install 3.11
# uv venv --python 3.11 .venv
# uv python install 3.12
# uv venv --python 3.12 .venv
# uv pip install --python .venv/bin/python --no-binary fastslide dist/*.tar.gz
# .venv/bin/python tools/smoke_test_python.py
smoke-wheels:
Expand All @@ -597,7 +576,9 @@ jobs:
strategy:
fail-fast: false
matrix:
python: ["3.10", "3.11", "3.12", "3.13", "3.14"]
# One cp312-abi3 wheel per platform, imported on every supported CPython
# (3.12-3.14) to prove the stable-ABI tag actually loads across versions.
python: ["3.12", "3.13", "3.14"]
target:
- platform: linux_x86_64
runner: ubuntu-24.04
Expand All @@ -614,12 +595,6 @@ jobs:
runner: windows-2022
- platform: windows_arm64
runner: windows-11-arm
# No official CPython 3.10 for Windows ARM64, so no cp310 win_arm64 wheel
# is built; drop that smoke combination.
exclude:
- python: "3.10"
target:
platform: windows_arm64
steps:
- name: Checkout
uses: actions/checkout@v5
Expand Down
17 changes: 0 additions & 17 deletions BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -1567,27 +1567,10 @@ cc_library(
visibility = ["//visibility:public"],
deps = [
":fastslide_lib",
":runtime_global_cache_manager",
":runtime_png_decoder",
],
)

# C API tile-cache tests. Require a real slide via FASTSLIDE_BENCHMARK_FILE;
# skipped otherwise. Run with:
# FASTSLIDE_BENCHMARK_FILE=/abs/path/CMU-3.ndpi \
# bazelisk test //:cache_c_api_test --test_output=all
cc_test(
name = "cache_c_api_test",
size = "small",
srcs = ["src/c/cache_c_api_test.cpp"],
deps = [
":fastslide_c",
":formats_ndpitiff",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
)

# Slide information tool
cc_binary(
name = "fastslidetool",
Expand Down
14 changes: 6 additions & 8 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -140,29 +140,27 @@ bazel_dep(name = "aspect_rules_js", version = "2.9.2", dev_dependency = True)
bazel_dep(name = "buildifier_prebuilt", version = "8.0.3", dev_dependency = True)
bazel_dep(name = "toolchains_llvm", version = "1.7.0", dev_dependency = True)

# The Python bindings ship a single stable-ABI (abi3) wheel floored at CPython
# 3.12, so only the 3.12 toolchain is registered. The extension built against it
# runs unchanged on every CPython >= 3.12.
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
python.toolchain(
is_default = True,
python_version = "3.11",
python_version = "3.12",
)
python.toolchain(python_version = "3.9")
python.toolchain(python_version = "3.10")
python.toolchain(python_version = "3.12")
python.toolchain(python_version = "3.13")
python.toolchain(python_version = "3.14")

pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
pip.parse(
enable_implicit_namespace_pkgs = True,
hub_name = "fastslide_pip",
python_version = "3.11",
python_version = "3.12",
requirements_darwin = "//:requirements_darwin.txt",
requirements_lock = "//:requirements_linux.txt",
)
pip.parse(
enable_implicit_namespace_pkgs = True,
hub_name = "fastslide_docs_pip",
python_version = "3.11",
python_version = "3.12",
requirements_darwin = "//docs:requirements_darwin.txt",
requirements_lock = "//docs:requirements_linux.txt",
)
Expand Down
25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,16 +125,17 @@ bazelisk test //...

##### Building Python wheels with Bazel

Wheels are platform-specific because they bundle the native C++ extension. Each
Python version has its own Bazel target: `//python:fastslide_wheel_cp310` through
`//python:fastslide_wheel_cp314` (Python 3.10–3.14). Unlike the Meson path,
Bazel can also cross-compile wheels for other platforms.
Wheels are platform-specific because they bundle the native C++ extension. A
single Bazel target, `//python:fastslide_wheel`, builds one stable-ABI wheel
tagged `cp312-abi3`; because it targets CPython's stable ABI, that wheel runs
on every CPython >= 3.12. Unlike the Meson path, Bazel can also cross-compile
wheels for other platforms.

**Current platform** — build on the host OS/arch without cross-compilation:

```bash
# Example: Python 3.11 wheel for the machine you are on.
bazelisk build //python:fastslide_wheel_cp311
# The cp312-abi3 wheel for the machine you are on.
bazelisk build //python:fastslide_wheel
```

The `.whl` file appears under `bazel-bin/python/`.
Expand All @@ -143,24 +144,24 @@ The `.whl` file appears under `bazel-bin/python/`.
hermetic toolchains (`--config=hermetic` in `.bazelrc`):

```bash
# Example: Linux x86_64 wheel for Python 3.11, e.g. from macOS.
# Example: Linux x86_64 wheel, e.g. from macOS.
bazelisk build --config=hermetic --platforms=//platforms:linux_x86_64 \
//python:fastslide_wheel_cp311
//python:fastslide_wheel
```

Supported platform keys: `linux_x86_64`, `linux_arm64`, `darwin_x86_64`,
`darwin_aarch64`, `windows_x86_64`. When building for the host macOS
architecture from macOS, the native toolchain is used instead of hermetic Zig.

**Batch builds** — `tools/build_wheels.py` drives Bazel for multiple platforms
and Python versions and copies wheels into `artifacts/wheels/`:
and copies wheels into `artifacts/wheels/`:

```bash
# All supported platforms and Python versions.
# All supported platforms.
python tools/build_wheels.py

# Subset, e.g. one platform and one Python tag.
python tools/build_wheels.py --platform linux_x86_64 --python cp311
# Subset, e.g. one platform.
python tools/build_wheels.py --platform linux_x86_64

# Continue after individual failures.
python tools/build_wheels.py --keep-going
Expand Down
Loading
Loading