mirror of https://github.com/google/benchmark.git
Modernize wheel building job config (#1783)
It is now possible to build Mac wheels on native machines in Github Actions, so ARM64 Mac wheels are now built and tested on M1 machines. Also, the artifact up-/download was migrated to v4, which made it necessary to upload wheels to unique artifact names, and then later stitch them together again in a subsequent job. The cross-platform Mac build injection in setup.py was removed, since it is no longer necessary. I relanded a monkey-patching of Bazel build files, this time for MODULE.bazel. This is because `rules_python` does not allow running as the root user, which is the case in cibuildwheel+Linux (happens in a Docker container). Since I did not see a quick way of switching to rootless containers, and did not want to hardcode the config change (it can apparently cause cache misses and build failures), I inject the "ignore_root_user_error" flag into the MODULE.bazel file when running in cibuildwheel on Linux.
This commit is contained in:
parent
185c55d793
commit
bc946b919c
|
@ -3,11 +3,10 @@ if ! bazel version; then
|
||||||
if [ "$arch" == "aarch64" ]; then
|
if [ "$arch" == "aarch64" ]; then
|
||||||
arch="arm64"
|
arch="arm64"
|
||||||
fi
|
fi
|
||||||
echo "Installing wget and downloading $arch Bazel binary from GitHub releases."
|
echo "Downloading $arch Bazel binary from GitHub releases."
|
||||||
yum install -y wget
|
curl -L -o $HOME/bin/bazel --create-dirs "https://github.com/bazelbuild/bazel/releases/download/7.1.1/bazel-7.1.1-linux-$arch"
|
||||||
wget "https://github.com/bazelbuild/bazel/releases/download/6.4.0/bazel-6.4.0-linux-$arch" -O /usr/local/bin/bazel
|
chmod +x $HOME/bin/bazel
|
||||||
chmod +x /usr/local/bin/bazel
|
|
||||||
else
|
else
|
||||||
# bazel is installed for the correct architecture
|
# Bazel is installed for the correct architecture
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -15,16 +15,16 @@ jobs:
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Install Python 3.11
|
- name: Install Python 3.12
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: 3.11
|
python-version: 3.12
|
||||||
- run: python -m pip install build
|
- run: python -m pip install build
|
||||||
- name: Build sdist
|
- name: Build sdist
|
||||||
run: python -m build --sdist
|
run: python -m build --sdist
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: dist
|
name: dist-sdist
|
||||||
path: dist/*.tar.gz
|
path: dist/*.tar.gz
|
||||||
|
|
||||||
build_wheels:
|
build_wheels:
|
||||||
|
@ -32,7 +32,7 @@ jobs:
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-13, macos-14, windows-latest]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check out Google Benchmark
|
- name: Check out Google Benchmark
|
||||||
|
@ -47,32 +47,44 @@ jobs:
|
||||||
platforms: all
|
platforms: all
|
||||||
|
|
||||||
- name: Build wheels on ${{ matrix.os }} using cibuildwheel
|
- name: Build wheels on ${{ matrix.os }} using cibuildwheel
|
||||||
uses: pypa/cibuildwheel@v2.16.2
|
uses: pypa/cibuildwheel@v2.17
|
||||||
env:
|
env:
|
||||||
CIBW_BUILD: 'cp38-* cp39-* cp310-* cp311-* cp312-*'
|
CIBW_BUILD: "cp38-* cp39-* cp310-* cp311-* cp312-*"
|
||||||
CIBW_SKIP: "*-musllinux_*"
|
CIBW_SKIP: "*-musllinux_*"
|
||||||
CIBW_TEST_SKIP: "*-macosx_arm64"
|
CIBW_TEST_SKIP: "cp38-macosx_*:arm64"
|
||||||
CIBW_ARCHS_LINUX: x86_64 aarch64
|
CIBW_ARCHS_LINUX: auto64 aarch64
|
||||||
CIBW_ARCHS_MACOS: x86_64 arm64
|
CIBW_ARCHS_WINDOWS: auto64
|
||||||
CIBW_ARCHS_WINDOWS: AMD64
|
|
||||||
CIBW_BEFORE_ALL_LINUX: bash .github/install_bazel.sh
|
CIBW_BEFORE_ALL_LINUX: bash .github/install_bazel.sh
|
||||||
|
# Grab the rootless Bazel installation inside the container.
|
||||||
|
CIBW_ENVIRONMENT_LINUX: PATH=$PATH:$HOME/bin
|
||||||
CIBW_TEST_COMMAND: python {project}/bindings/python/google_benchmark/example.py
|
CIBW_TEST_COMMAND: python {project}/bindings/python/google_benchmark/example.py
|
||||||
|
|
||||||
- name: Upload Google Benchmark ${{ matrix.os }} wheels
|
- name: Upload Google Benchmark ${{ matrix.os }} wheels
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: dist-${{ matrix.os }}
|
||||||
|
path: wheelhouse/*.whl
|
||||||
|
|
||||||
|
merge_wheels:
|
||||||
|
name: Merge all built wheels into one artifact
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build_wheels
|
||||||
|
steps:
|
||||||
|
- name: Merge wheels
|
||||||
|
uses: actions/upload-artifact/merge@v4
|
||||||
with:
|
with:
|
||||||
name: dist
|
name: dist
|
||||||
path: wheelhouse/*.whl
|
pattern: dist-*
|
||||||
|
delete-merged: true
|
||||||
|
|
||||||
pypi_upload:
|
pypi_upload:
|
||||||
name: Publish google-benchmark wheels to PyPI
|
name: Publish google-benchmark wheels to PyPI
|
||||||
needs: [build_sdist, build_wheels]
|
needs: [merge_wheels]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
id-token: write
|
id-token: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: dist
|
path: dist
|
||||||
path: dist
|
- uses: pypa/gh-action-pypi-publish@v1
|
||||||
- uses: pypa/gh-action-pypi-publish@v1.8.11
|
|
||||||
|
|
|
@ -27,10 +27,6 @@ python.toolchain(
|
||||||
is_default = True,
|
is_default = True,
|
||||||
python_version = "3.12",
|
python_version = "3.12",
|
||||||
)
|
)
|
||||||
use_repo(
|
|
||||||
python,
|
|
||||||
python = "python_versions",
|
|
||||||
)
|
|
||||||
|
|
||||||
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip", dev_dependency = True)
|
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip", dev_dependency = True)
|
||||||
pip.parse(
|
pip.parse(
|
||||||
|
|
63
setup.py
63
setup.py
|
@ -1,14 +1,17 @@
|
||||||
|
import contextlib
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any, Generator
|
||||||
|
|
||||||
import setuptools
|
import setuptools
|
||||||
from setuptools.command import build_ext
|
from setuptools.command import build_ext
|
||||||
|
|
||||||
IS_WINDOWS = platform.system() == "Windows"
|
IS_WINDOWS = platform.system() == "Windows"
|
||||||
IS_MAC = platform.system() == "Darwin"
|
IS_MAC = platform.system() == "Darwin"
|
||||||
|
IS_LINUX = platform.system() == "Linux"
|
||||||
|
|
||||||
# hardcoded SABI-related options. Requires that each Python interpreter
|
# hardcoded SABI-related options. Requires that each Python interpreter
|
||||||
# (hermetic or not) participating is of the same major-minor version.
|
# (hermetic or not) participating is of the same major-minor version.
|
||||||
|
@ -17,6 +20,46 @@ py_limited_api = version_tuple >= (3, 12)
|
||||||
options = {"bdist_wheel": {"py_limited_api": "cp312"}} if py_limited_api else {}
|
options = {"bdist_wheel": {"py_limited_api": "cp312"}} if py_limited_api else {}
|
||||||
|
|
||||||
|
|
||||||
|
def is_cibuildwheel() -> bool:
|
||||||
|
return os.getenv("CIBUILDWHEEL") is not None
|
||||||
|
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def _maybe_patch_toolchains() -> Generator[None, None, None]:
|
||||||
|
"""
|
||||||
|
Patch rules_python toolchains to ignore root user error
|
||||||
|
when run in a Docker container on Linux in cibuildwheel.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def fmt_toolchain_args(matchobj):
|
||||||
|
suffix = "ignore_root_user_error = True"
|
||||||
|
callargs = matchobj.group(1)
|
||||||
|
# toolchain def is broken over multiple lines
|
||||||
|
if callargs.endswith("\n"):
|
||||||
|
callargs = callargs + " " + suffix + ",\n"
|
||||||
|
# toolchain def is on one line.
|
||||||
|
else:
|
||||||
|
callargs = callargs + ", " + suffix
|
||||||
|
return "python.toolchain(" + callargs + ")"
|
||||||
|
|
||||||
|
CIBW_LINUX = is_cibuildwheel() and IS_LINUX
|
||||||
|
try:
|
||||||
|
if CIBW_LINUX:
|
||||||
|
module_bazel = Path("MODULE.bazel")
|
||||||
|
content: str = module_bazel.read_text()
|
||||||
|
module_bazel.write_text(
|
||||||
|
re.sub(
|
||||||
|
r"python.toolchain\(([\w\"\s,.=]*)\)",
|
||||||
|
fmt_toolchain_args,
|
||||||
|
content,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
if CIBW_LINUX:
|
||||||
|
module_bazel.write_text(content)
|
||||||
|
|
||||||
|
|
||||||
class BazelExtension(setuptools.Extension):
|
class BazelExtension(setuptools.Extension):
|
||||||
"""A C/C++ extension that is defined as a Bazel BUILD target."""
|
"""A C/C++ extension that is defined as a Bazel BUILD target."""
|
||||||
|
|
||||||
|
@ -73,21 +116,11 @@ class BuildBazelExtension(build_ext.build_ext):
|
||||||
for library_dir in self.library_dirs:
|
for library_dir in self.library_dirs:
|
||||||
bazel_argv.append("--linkopt=/LIBPATH:" + library_dir)
|
bazel_argv.append("--linkopt=/LIBPATH:" + library_dir)
|
||||||
elif IS_MAC:
|
elif IS_MAC:
|
||||||
if platform.machine() == "x86_64":
|
# C++17 needs macOS 10.14 at minimum
|
||||||
# C++17 needs macOS 10.14 at minimum
|
bazel_argv.append("--macos_minimum_os=10.14")
|
||||||
bazel_argv.append("--macos_minimum_os=10.14")
|
|
||||||
|
|
||||||
# cross-compilation for Mac ARM64 on GitHub Mac x86 runners.
|
with _maybe_patch_toolchains():
|
||||||
# ARCHFLAGS is set by cibuildwheel before macOS wheel builds.
|
self.spawn(bazel_argv)
|
||||||
archflags = os.getenv("ARCHFLAGS", "")
|
|
||||||
if "arm64" in archflags:
|
|
||||||
bazel_argv.append("--cpu=darwin_arm64")
|
|
||||||
bazel_argv.append("--macos_cpus=arm64")
|
|
||||||
|
|
||||||
elif platform.machine() == "arm64":
|
|
||||||
bazel_argv.append("--macos_minimum_os=11.0")
|
|
||||||
|
|
||||||
self.spawn(bazel_argv)
|
|
||||||
|
|
||||||
if IS_WINDOWS:
|
if IS_WINDOWS:
|
||||||
suffix = ".pyd"
|
suffix = ".pyd"
|
||||||
|
|
Loading…
Reference in New Issue