Skip to content
Merged
Show file tree
Hide file tree
Changes from 69 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
3a3caec
Add Android to resource files
mhsmith Apr 4, 2025
578c181
Add Android to miscellaneous places
mhsmith Apr 4, 2025
c720392
Add Android documentation
mhsmith Apr 15, 2025
e33235d
Merge remote-tracking branch 'origin/main' into android
mhsmith Apr 17, 2025
8e03e87
Docs cleanups
mhsmith Apr 17, 2025
4428868
Add Android platform module; implement top-level structure and target…
mhsmith Apr 23, 2025
f3084f0
Implement setup_env and build_wheel
mhsmith Apr 23, 2025
e715aa4
lru-dict build working
mhsmith Apr 25, 2025
4234013
Alter prefix in sysconfigdata file; fix various issues with FLAGS var…
mhsmith Apr 30, 2025
f2048b7
Implement Android testing
mhsmith May 4, 2025
ec1a6c5
Merge remote-tracking branch 'origin/main' into android
mhsmith May 4, 2025
be664be
Add type annotations to _cross_venv
mhsmith May 4, 2025
d56114b
Revert Python 3.8 to pip 25.0.1
mhsmith May 5, 2025
13003df
Merge remote-tracking branch 'origin/main' into android
mhsmith May 5, 2025
71ba70d
Make test-sources required on Android
mhsmith May 5, 2025
e1ef58f
Add Android integration tests
mhsmith May 6, 2025
40ac49a
Test cleanups
mhsmith May 28, 2025
535bb74
Add test of all available Python versions
mhsmith May 28, 2025
45e08c0
Merge remote-tracking branch 'origin/main' into android
mhsmith May 28, 2025
00b7cc1
Update test-sources and test-command behavior to match iOS
mhsmith May 28, 2025
83f6073
Documentation cleanups
mhsmith May 28, 2025
2bfc2fd
Merge remote-tracking branch 'origin/main' into android
mhsmith May 29, 2025
6e90e01
Replace Builder class with a set of global functions
mhsmith May 30, 2025
f1d86d0
Rename "env" to "build_env"
mhsmith May 30, 2025
bcc2207
Merge remote-tracking branch 'origin/main' into android
mhsmith May 30, 2025
6ab5c3f
Remove Chaquopy repository from default pip command line
mhsmith May 30, 2025
2bbab57
Move native_platform to platforms module
mhsmith May 30, 2025
b57b9e6
Fix parse_config_settings
mhsmith May 30, 2025
95a631a
Add unit tests for parse_config_settings and arch_synonym
mhsmith May 30, 2025
70ba326
Make `shell_prepared` arguments keyword-only, and add tests for the c…
mhsmith May 31, 2025
b191c0a
Replace `importlib.util.spec_from_file_location` with `runpy.run_path`
mhsmith May 31, 2025
7c0a95a
Use python-build-standalone
mhsmith May 31, 2025
5ebd015
Update Android Python
mhsmith May 31, 2025
4e9b82b
Enable KVM in Linux CI
mhsmith Jun 2, 2025
e775aca
Move KVM code to test_android.py
mhsmith Jun 2, 2025
4e94ceb
Use Java 17 on Azure
mhsmith Jun 2, 2025
3dde388
Install emulator if necessary before running -accel-check
mhsmith Jun 2, 2025
16d2a45
Free up additional disk space on Linux runners
mhsmith Jun 3, 2025
5203f2a
Merge remote-tracking branch 'origin/main' into android
mhsmith Jun 3, 2025
f072818
Add sudo
mhsmith Jun 3, 2025
d6890a8
Skip emulator tests on CI platforms that don't support it
mhsmith Jun 3, 2025
62817d8
Download Android Python from Maven Central
mhsmith Jun 3, 2025
01e787f
Free up more disk space on Linux runners
mhsmith Jun 3, 2025
34623ff
fix: minor fixups
henryiii Jun 4, 2025
42daec5
Merge branch 'main' into android
henryiii Jun 5, 2025
be84165
Set sysconfig._BASE_PREFIX to support sysconfig.get_path("include")
mhsmith Jun 9, 2025
be2cf54
Get ANDROID_API_LEVEL from the build environment, not cibuildwheel's …
mhsmith Jun 9, 2025
93eda75
Merge remote-tracking branch 'mhsmith/android' into android
mhsmith Jun 9, 2025
405fd06
Correct relative path of test-sources
mhsmith Jun 10, 2025
db9796b
Pass a CMake toolchain file to the build
mhsmith Jun 11, 2025
61407dd
Merge remote-tracking branch 'origin/main' into android
mhsmith Jun 11, 2025
c63753c
Add "repair" step which adds libc++ to the wheel when necessary
mhsmith Jun 11, 2025
60eb070
Add missing needs_emulator decorator
mhsmith Jun 11, 2025
a16d47a
Provide useful error message if ANDROID_HOME is not set
mhsmith Jun 16, 2025
933abfd
Merge remote-tracking branch 'origin/main' into android
mhsmith Jun 16, 2025
0ba3281
Remove use of HOST environment variable
mhsmith Jun 16, 2025
a1aedd5
Update to Python 3.15.5
mhsmith Jul 11, 2025
8a41764
Fix PyLint warnings, clarify comment
mhsmith Jul 11, 2025
75b1e9e
Merge remote-tracking branch 'origin/main' into android
mhsmith Jul 11, 2025
bffdb04
Group common arguments into a dataclass
mhsmith Jul 15, 2025
822dda7
Handle environment variables containing newlines
mhsmith Jul 15, 2025
bfb3e5e
Discourage the use of `pytest` test commands without `python -m`
mhsmith Jul 15, 2025
eda1637
Use single quotes in user-visible messages
mhsmith Jul 15, 2025
c2c71b6
Merge remote-tracking branch 'origin/main' into android
mhsmith Jul 16, 2025
cc6251c
Improve testing documentation
mhsmith Jul 16, 2025
e281bfb
Merge remote-tracking branch 'origin/main' into android
mhsmith Jul 16, 2025
691556f
Pass wheel filename to `log.build_end`
mhsmith Jul 16, 2025
d83bb42
In GitHub Actions example, skip Android tests on macOS
mhsmith Jul 16, 2025
cee4b16
Correct relative paths in `patchelf --set-rpath`
mhsmith Jul 17, 2025
d1aae4b
Clarify `test-sources` docs
mhsmith Jul 20, 2025
416ef03
Update to Python 3.13.5+20250722.214220
mhsmith Jul 22, 2025
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
14 changes: 12 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,23 @@ jobs:

- uses: astral-sh/setup-uv@v6

# free some space to prevent reaching GHA disk space limits
- name: Clean docker images
- name: Free up disk space
if: runner.os == 'Linux'
run: |
docker system prune -a -f
sudo rm -rf $ANDROID_HOME/ndk/{26,28}.* /opt/hostedtoolcache/CodeQL \
/usr/local/lib/node_modules /usr/local/share/chromium \
/usr/local/share/powershell
df -h

# https://github.blog/changelog/2024-04-02-github-actions-hardware-accelerated-android-virtualization-now-available/
- name: Enable KVM for Android emulator
if: runner.os == 'Linux' && runner.arch == 'X64'
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm

# for oci_container unit tests
- name: Set up QEMU
if: runner.os == 'Linux'
Expand Down
4 changes: 3 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,16 @@ repos:
- id: mypy
name: mypy 3.11 on cibuildwheel/
args: ["--python-version=3.11"]
exclude: ^cibuildwheel/resources/_cross_venv.py$ # Requires Python 3.13 or later
additional_dependencies: &mypy-dependencies
- bracex
- build
- dependency-groups>=1.2
- humanize
- nox>=2025.2.9
- orjson
- packaging
- pyelftools
- pygithub
- pytest
- rich
Expand All @@ -47,7 +50,6 @@ repos:
- validate-pyproject
- id: mypy
name: mypy 3.13
exclude: ^cibuildwheel/resources/.*py$
args: ["--python-version=3.13"]
additional_dependencies: *mypy-dependencies

Expand Down
48 changes: 24 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,20 @@ What does it do?

While cibuildwheel itself requires a recent Python version to run (we support the last three releases), it can target the following versions to build wheels:

| | macOS Intel | macOS Apple Silicon | Windows 64bit | Windows 32bit | Windows Arm64 | manylinux<br/>musllinux x86_64 | manylinux<br/>musllinux i686 | manylinux<br/>musllinux aarch64 | manylinux<br/>musllinux ppc64le | manylinux<br/>musllinux s390x | manylinux<br/>musllinux armv7l | iOS | Pyodide |
|--------------------|----|-----|-----|-----|-----|----|-----|----|-----|-----|---|-----|-----|
| CPython 3.8 | ✅ | ✅ | ✅ | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A | N/A |
| CPython 3.9 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A | N/A |
| CPython 3.10 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A | N/A |
| CPython 3.11 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A | N/A |
| CPython 3.12 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A | ✅⁴ |
| CPython 3.13³ | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | ✅ | N/A |
| CPython 3.14³ | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | | N/A |
| PyPy 3.8 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | N/A | N/A |
| PyPy 3.9 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | N/A | N/A |
| PyPy 3.10 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | N/A | N/A |
| PyPy 3.11 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | N/A | N/A |
| GraalPy 3.11 v24.2 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | N/A | ✅¹ | N/A | N/A | N/A | N/A | N/A |
| | macOS Intel | macOS Apple Silicon | Windows 64bit | Windows 32bit | Windows Arm64 | manylinux<br/>musllinux x86_64 | manylinux<br/>musllinux i686 | manylinux<br/>musllinux aarch64 | manylinux<br/>musllinux ppc64le | manylinux<br/>musllinux s390x | manylinux<br/>musllinux armv7l | Android | iOS | Pyodide |
|--------------------|----|-----|----|-----|-----|----|-----|----|-----|-----|---|-----|-----|-----|
| CPython 3.8 | ✅ | ✅ | ✅ | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A | N/A | N/A |
| CPython 3.9 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A | N/A | N/A |
| CPython 3.10 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A | N/A | N/A |
| CPython 3.11 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A | N/A | N/A |
| CPython 3.12 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A | N/A | ✅⁴ |
| CPython 3.13³ | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | ✅ | ✅ | N/A |
| CPython 3.14³ | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A | N/A | N/A |
| PyPy 3.8 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | N/A | N/A | N/A |
| PyPy 3.9 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | N/A | N/A | N/A |
| PyPy 3.10 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | N/A | N/A | N/A |
| PyPy 3.11 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | N/A | N/A | N/A |
| GraalPy 3.11 v24.2 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | N/A | ✅¹ | N/A | N/A | N/A | N/A | N/A | N/A |

<sup>¹ PyPy & GraalPy are only supported for manylinux wheels.</sup><br>
<sup>² Windows arm64 support is experimental.</sup><br>
Expand All @@ -56,19 +56,19 @@ Usage

`cibuildwheel` runs inside a CI service. Supported platforms depend on which service you're using:

| | Linux | macOS | Windows | Linux ARM | macOS ARM | Windows ARM | iOS |
|-----------------|-------|-------|---------|-----------|-----------|-------------|-----|
| GitHub Actions | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅³ |
| Azure Pipelines | ✅ | ✅ | ✅ | | ✅ | ✅² | ✅³ |
| Travis CI | ✅ | | ✅ | ✅ | | | |
| CircleCI | ✅ | ✅ | | ✅ | ✅ | | ✅³ |
| Gitlab CI | ✅ | ✅ | ✅ | ✅¹ | ✅ | | ✅³ |
| Cirrus CI | ✅ | ✅ | ✅ | ✅ | ✅ | | |
| | Linux | macOS | Windows | Linux ARM | macOS ARM | Windows ARM | Android | iOS |
|-----------------|-------|-------|---------|-----------|-----------|-------------|---------|-----|
| GitHub Actions | ✅ | ✅ | ✅ | ✅ | ✅ | ✅² | ✅⁴ | ✅³ |
| Azure Pipelines | ✅ | ✅ | ✅ | | ✅ | ✅² | ✅⁴ | ✅³ |
| Travis CI | ✅ | | ✅ | ✅ | | | ✅⁴ | |
| CircleCI | ✅ | ✅ | | ✅ | ✅ | | ✅⁴ | ✅³ |
| Gitlab CI | ✅ | ✅ | ✅ | ✅¹ | ✅ | | ✅⁴ | ✅³ |
| Cirrus CI | ✅ | ✅ | ✅ | ✅ | ✅ | | ✅⁴ | |

<sup>¹ [Requires emulation](https://cibuildwheel.pypa.io/en/stable/faq/#emulation), distributed separately. Other services may also support Linux ARM through emulation or third-party build hosts, but these are not tested in our CI.</sup><br>
<sup>² [Uses cross-compilation](https://cibuildwheel.pypa.io/en/stable/faq/#windows-arm64). It is not possible to test `arm64` on this CI platform.</sup><br>
<sup>³ Requires a macOS runner; runs tests on the simulator for the runner's architecture.</sup>

<sup>³ Requires a macOS runner; runs tests on the simulator for the runner's architecture.</sup><br>
<sup>⁴ Building for Android requires the runner to be Linux x86_64, macOS ARM64 or macOS x86_64. Testing has [additional requirements](https://cibuildwheel.pypa.io/en/stable/platforms/#android).</sup><br>
<!--intro-end-->

Example setup
Expand Down
5 changes: 5 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ jobs:
- task: UsePythonVersion@0
inputs:
versionSpec: '3.11'
- task: JavaToolInstaller@0
inputs:
versionSpec: '17'
jdkArchitectureOption: 'x64'
jdkSourceOption: 'PreInstalled'
- bash: |
docker run --rm --privileged docker.io/tonistiigi/binfmt:latest --install all
python -m pip install -U pip
Expand Down
1 change: 1 addition & 0 deletions bin/generate_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ def as_object(d: dict[str, Any]) -> dict[str, Any]:
"windows": as_object(not_linux),
"macos": as_object(not_linux),
"pyodide": as_object(not_linux),
"android": as_object(not_linux),
"ios": as_object(not_linux),
}

Expand Down
60 changes: 48 additions & 12 deletions bin/update_pythons.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from collections.abc import Mapping, MutableMapping
from pathlib import Path
from typing import Any, Final, Literal, TypedDict
from xml.etree import ElementTree as ET

import click
import requests
Expand All @@ -20,6 +21,7 @@
from rich.syntax import Syntax

from cibuildwheel.extra import dump_python_configurations, get_pyodide_xbuildenv_info
from cibuildwheel.platforms.android import android_triplet

log = logging.getLogger("cibw")

Expand Down Expand Up @@ -57,14 +59,20 @@ class ConfigApple(TypedDict):
url: str


class ConfigAndroid(TypedDict):
identifier: str
version: str
url: str


class ConfigPyodide(TypedDict):
identifier: str
version: str
default_pyodide_version: str
node_version: str


AnyConfig = ConfigWinCP | ConfigWinPP | ConfigWinGP | ConfigApple | ConfigPyodide
AnyConfig = ConfigWinCP | ConfigWinPP | ConfigWinGP | ConfigApple | ConfigAndroid | ConfigPyodide


# The following set of "Versions" classes allow the initial call to the APIs to
Expand Down Expand Up @@ -320,6 +328,39 @@ def update_version_macos(
return None


class AndroidVersions:
# This should be replaced with official python.org downloads once they're available.
MAVEN_URL = "https://repo.maven.apache.org/maven2/com/chaquo/python/python"

def __init__(self) -> None:
response = requests.get(f"{self.MAVEN_URL}/maven-metadata.xml")
response.raise_for_status()
root = ET.fromstring(response.text)

self.versions: list[Version] = []
for version_elem in root.findall("./versioning/versions/version"):
version_str = version_elem.text
assert isinstance(version_str, str), version_str
self.versions.append(Version(version_str))

def update_version_android(
self, identifier: str, version: Version, spec: Specifier
) -> ConfigAndroid | None:
sorted_versions = sorted(spec.filter(self.versions), reverse=True)

# Return a config using the highest version for the given specifier.
if sorted_versions:
max_version = sorted_versions[0]
triplet = android_triplet(identifier)
return ConfigAndroid(
identifier=identifier,
version=str(version),
url=f"{self.MAVEN_URL}/{max_version}/python-{max_version}-{triplet}.tar.gz",
)
else:
return None


class CPythonIOSVersions:
def __init__(self) -> None:
response = requests.get(
Expand Down Expand Up @@ -413,6 +454,7 @@ def __init__(self) -> None:
self.macos_pypy = PyPyVersions("64")
self.macos_pypy_arm64 = PyPyVersions("ARM64")

self.android = AndroidVersions()
self.ios_cpython = CPythonIOSVersions()

self.graalpy = GraalPyVersions()
Expand Down Expand Up @@ -455,6 +497,8 @@ def update_config(self, config: MutableMapping[str, str]) -> None:
config_update = self.windows_t_arm64.update_version_windows(spec)
elif "win_arm64" in identifier and identifier.startswith("cp"):
config_update = self.windows_arm64.update_version_windows(spec)
elif "android" in identifier:
config_update = self.android.update_version_android(identifier, version, spec)
elif "ios" in identifier:
config_update = self.ios_cpython.update_version_ios(identifier, version)
elif "pyodide" in identifier:
Expand Down Expand Up @@ -490,17 +534,9 @@ def update_pythons(force: bool, level: str) -> None:
with toml_file_path.open("rb") as f:
configs = tomllib.load(f)

for config in configs["windows"]["python_configurations"]:
all_versions.update_config(config)

for config in configs["macos"]["python_configurations"]:
all_versions.update_config(config)

for config in configs["ios"]["python_configurations"]:
all_versions.update_config(config)

for config in configs["pyodide"]["python_configurations"]:
all_versions.update_config(config)
for platform in ["windows", "macos", "android", "ios", "pyodide"]:
for config in configs[platform]["python_configurations"]:
all_versions.update_config(config)

result_toml = dump_python_configurations(configs)

Expand Down
28 changes: 7 additions & 21 deletions cibuildwheel/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from cibuildwheel.ci import CIProvider, detect_ci_provider, fix_ansi_codes_for_github_actions
from cibuildwheel.logger import log
from cibuildwheel.options import CommandLineArguments, Options, compute_options
from cibuildwheel.platforms import ALL_PLATFORM_MODULES, get_build_identifiers
from cibuildwheel.platforms import ALL_PLATFORM_MODULES, get_build_identifiers, native_platform
from cibuildwheel.selector import BuildSelector, EnableGroup, selector_matches
from cibuildwheel.typing import PLATFORMS, PlatformName
from cibuildwheel.util.file import CIBW_CACHE_PATH
Expand Down Expand Up @@ -93,14 +93,14 @@ def main_inner(global_options: GlobalOptions) -> None:

parser.add_argument(
"--platform",
choices=["auto", "linux", "macos", "windows", "pyodide", "ios"],
choices=["auto", "linux", "macos", "windows", "pyodide", "android", "ios"],
default=None,
help="""
Platform to build for. Use this option to override the auto-detected
platform. Specifying "macos" or "windows" only works on that
operating system. "linux" works on any desktop OS, as long as
Docker/Podman is installed. "pyodide" only works on linux and macOS.
"ios" only work on macOS. Default: auto.
Docker/Podman is installed. "pyodide" and "android" only work on
Linux and macOS. "ios" only works on macOS. Default: auto.
""",
)

Expand Down Expand Up @@ -241,28 +241,14 @@ def _compute_platform_only(only: str) -> PlatformName:
return "windows"
if "pyodide_" in only:
return "pyodide"
if "android_" in only:
return "android"
if "ios_" in only:
return "ios"
msg = f"Invalid --only='{only}', must be a build selector with a known platform"
raise errors.ConfigurationError(msg)


def _compute_platform_auto() -> PlatformName:
if sys.platform.startswith("linux"):
return "linux"
elif sys.platform == "darwin":
return "macos"
elif sys.platform == "win32":
return "windows"
else:
msg = (
'Unable to detect platform from "sys.platform". cibuildwheel doesn\'t '
"support building wheels for this platform. You might be able to build for a different "
"platform using the --platform argument. Check --help output for more information."
)
raise errors.ConfigurationError(msg)


def _compute_platform(args: CommandLineArguments) -> PlatformName:
platform_option_value = args.platform or os.environ.get("CIBW_PLATFORM", "") or "auto"

Expand All @@ -282,7 +268,7 @@ def _compute_platform(args: CommandLineArguments) -> PlatformName:
elif platform_option_value != "auto":
return typing.cast(PlatformName, platform_option_value)

return _compute_platform_auto()
return native_platform()


def build_in_directory(args: CommandLineArguments) -> None:
Expand Down
32 changes: 21 additions & 11 deletions cibuildwheel/architecture.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,25 @@
"macos": "macOS",
"windows": "Windows",
"pyodide": "Pyodide",
"android": "Android",
"ios": "iOS",
}

ARCH_SYNONYMS: Final[list[dict[PlatformName, str | None]]] = [
{"linux": "x86_64", "macos": "x86_64", "windows": "AMD64"},
{"linux": "x86_64", "macos": "x86_64", "windows": "AMD64", "android": "x86_64"},
{"linux": "i686", "macos": None, "windows": "x86"},
{"linux": "aarch64", "macos": "arm64", "windows": "ARM64"},
{"linux": "aarch64", "macos": "arm64", "windows": "ARM64", "android": "arm64_v8a"},
]


def arch_synonym(arch: str, from_platform: PlatformName, to_platform: PlatformName) -> str | None:
for arch_synonym_ in ARCH_SYNONYMS:
if arch == arch_synonym_.get(from_platform):
return arch_synonym_.get(to_platform, arch)

return arch


def _check_aarch32_el0() -> bool:
"""Check if running armv7l natively on aarch64 is supported"""
if not sys.platform.startswith("linux"):
Expand All @@ -42,7 +51,7 @@ def _check_aarch32_el0() -> bool:

@typing.final
class Architecture(StrEnum):
# mac/linux archs
# mac/linux/android archs
x86_64 = auto()

# linux archs
Expand All @@ -65,6 +74,9 @@ class Architecture(StrEnum):
# WebAssembly
wasm32 = auto()

# android archs
arm64_v8a = auto()

# iOS "multiarch" architectures that include both
# the CPU architecture and the ABI.
arm64_iphoneos = auto()
Expand Down Expand Up @@ -123,15 +135,12 @@ def native_arch(platform: PlatformName) -> "Architecture | None":
# we might need to rename the native arch to the machine we're running
# on, as the same arch can have different names on different platforms
if host_platform != platform:
for arch_synonym in ARCH_SYNONYMS:
if native_machine == arch_synonym.get(host_platform):
synonym = arch_synonym[platform]

if synonym is None:
# can't build anything on this platform
return None
synonym = arch_synonym(native_machine, host_platform, platform)
if synonym is None:
# can't build anything on this platform
return None

native_architecture = Architecture(synonym)
native_architecture = Architecture(synonym)

return native_architecture

Expand Down Expand Up @@ -166,6 +175,7 @@ def all_archs(platform: PlatformName) -> "set[Architecture]":
"macos": {Architecture.x86_64, Architecture.arm64, Architecture.universal2},
"windows": {Architecture.x86, Architecture.AMD64, Architecture.ARM64},
"pyodide": {Architecture.wasm32},
"android": {Architecture.x86_64, Architecture.arm64_v8a},
"ios": {
Architecture.x86_64_iphonesimulator,
Architecture.arm64_iphonesimulator,
Expand Down
Loading
Loading