feat: add support for building Android wheels (#2349)

* Add Android to resource files

* Add Android to miscellaneous places

* Add Android documentation

* Docs cleanups

* Add Android platform module; implement top-level structure and target Python installation

* Implement setup_env and build_wheel

* lru-dict build working

* Alter prefix in sysconfigdata file; fix various issues with FLAGS variables

* Implement Android testing

* Add type annotations to _cross_venv

* Revert Python 3.8 to pip 25.0.1

* Make test-sources required on Android

* Add Android integration tests

* Test cleanups

* Add test of all available Python versions

* Update test-sources and test-command behavior to match iOS

* Documentation cleanups

* Replace Builder class with a set of global functions

* Rename "env" to "build_env"

* Remove Chaquopy repository from default pip command line

* Move native_platform to platforms module

* Fix parse_config_settings

Co-authored-by: Joe Rickerby <joerick@mac.com>

* Add unit tests for parse_config_settings and arch_synonym

* Make `shell_prepared` arguments keyword-only, and add tests for the commands that use it

* Replace `importlib.util.spec_from_file_location` with `runpy.run_path`

* Use python-build-standalone

* Update Android Python

* Enable KVM in Linux CI

* Move KVM code to test_android.py

* Use Java 17 on Azure

* Install emulator if necessary before running -accel-check

* Free up additional disk space on Linux runners

* Add sudo

* Skip emulator tests on CI platforms that don't support it

* Download Android Python from Maven Central

* Free up more disk space on Linux runners

* fix: minor fixups

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* Set sysconfig._BASE_PREFIX to support sysconfig.get_path("include")

* Get ANDROID_API_LEVEL from the build environment, not cibuildwheel's own environment

* Correct relative path of test-sources

* Pass a CMake toolchain file to the build

* Add "repair" step which adds libc++ to the wheel when necessary

* Add missing needs_emulator decorator

* Provide useful error message if ANDROID_HOME is not set

* Remove use of HOST environment variable

* Update to Python 3.15.5

* Fix PyLint warnings, clarify comment

* Group common arguments into a dataclass

* Handle environment variables containing newlines

* Discourage the use of `pytest` test commands without `python -m`

* Use single quotes in user-visible messages

* Improve testing documentation

* Pass wheel filename to `log.build_end`

* In GitHub Actions example, skip Android tests on macOS

* Correct relative paths in `patchelf --set-rpath`

* Clarify `test-sources` docs

* Update to Python 3.13.5+20250722.214220

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: Joe Rickerby <joerick@mac.com>
Co-authored-by: Henry Schreiner <henryschreineriii@gmail.com>
This commit is contained in:
Malcolm Smith
2025-07-23 17:18:33 -04:00
committed by GitHub
co-authored by Joe Rickerby Henry Schreiner
parent e2e24882d8
commit 0f487ee2cb
38 changed files with 1548 additions and 160 deletions
+9 -2
View File
@@ -151,7 +151,7 @@ def cibuildwheel_run(
cwd=project_path,
check=True,
)
wheels = [p.name for p in (output_dir or Path(tmp_output_dir)).iterdir()]
wheels = sorted(p.name for p in (output_dir or Path(tmp_output_dir)).iterdir())
return wheels
@@ -262,7 +262,7 @@ def _expected_wheels(
if platform == "pyodide" and python_abi_tags is None:
python_abi_tags = ["cp312-cp312", "cp313-cp313"]
elif platform == "ios" and python_abi_tags is None:
elif platform in {"android", "ios"} and python_abi_tags is None:
python_abi_tags = ["cp313-cp313"]
elif python_abi_tags is None:
python_abi_tags = [
@@ -367,6 +367,13 @@ def _expected_wheels(
if include_universal2:
platform_tags.append(f"macosx_{min_macosx.replace('.', '_')}_universal2")
elif platform == "android":
api_level = {
"cp313-cp313": 21,
"cp314-cp314": 24,
}[python_abi_tag]
platform_tags = [f"android_{api_level}_{machine_arch}"]
elif platform == "ios":
if machine_arch == "x86_64":
platform_tags = [