From 1cf64d0d3cece37101260d1c0ba7ad011f0be28e Mon Sep 17 00:00:00 2001 From: Malcolm Smith Date: Fri, 29 May 2026 05:27:28 +0100 Subject: [PATCH] feat: Android improvements needed for building NumPy and related packages (#2695) * Use auditwheel on Android * Add auditwheel command to defaults * pkgconfig fixes * Pre-import ctypes before monkey-patching in _cross_venv * Set PKG_CONFIG and PKG_CONFIG_RELOCATE_PATHS variables * Initial attempt at using mzakharo/android-gfortran * Switch to using termux/ndk-toolchain-clang-with-flang * Move PKG_CONFIG variables from build_env to android_env * Simplify flang installation * Add cross build files for NumPy * Add ldpaths entry for libomp * Add `--rm` to docker command line * Make Rust and Fortran shims consistent * Update documentation * Default to API level 24 on all Python versions * Clarify comments * Cleanups * Fix tests: * Set up Android env after installing pkgconf * Add tests for successfully using an older API level * Previous commit's auditwheel failure is fixed in the auditwheel PR * Update how-it-works diagram * Add tests for repair errors * Add more repair tests * Add test for Meson and Fortran * Add test for cross build files * Improve test_api_level error message * Add xbuild-files option * use pypa/auditwheel@main * Remove dependencies which are no longer needed * Fix README * Update to auditwheel 6.7.0 * Fix compatibility with pkgconf 2.5.1.post2 * Documentation clarifications Co-authored-by: Joe Rickerby * Fortran shim improvements * Add Jinja variables to new_meson_project * Update run_example_ci_configs for changed new_meson_project signature * Add missing dependency to run_example_ci_configs --------- Co-authored-by: mayeut Co-authored-by: Joe Rickerby --- .pre-commit-config.yaml | 1 - README.md | 3 +- bin/generate_schema.py | 23 +- bin/run_example_ci_configs.py | 10 +- cibuildwheel/options.py | 10 + cibuildwheel/platforms/android.py | 310 ++++++++---------- cibuildwheel/resources/android/_cross_venv.py | 3 + .../resources/android/fortran_shim.py | 121 +++++++ .../resources/cibuildwheel.schema.json | 67 +++- .../resources/constraints-python310.txt | 11 +- .../resources/constraints-python311.txt | 11 +- .../resources/constraints-python312.txt | 11 +- .../resources/constraints-python313.txt | 11 +- .../resources/constraints-python314.txt | 11 +- .../resources/constraints-python315.txt | 11 +- .../resources/constraints-python39.txt | 15 +- cibuildwheel/resources/constraints.in | 5 + cibuildwheel/resources/constraints.txt | 11 +- cibuildwheel/resources/defaults.toml | 11 + cibuildwheel/util/helpers.py | 4 +- docs/configuration.md | 4 +- docs/data/how-it-works.png | Bin 98369 -> 98793 bytes docs/diagram.html | 4 +- docs/options.md | 33 +- docs/platforms.md | 10 +- pyproject.toml | 4 - test/test_android.py | 214 +++++++++++- test/test_projects/meson.py | 6 + test/test_projects/setuptools.py | 3 +- test/utils.py | 13 +- unit_test/options_test.py | 48 +++ unit_test/utils_test.py | 22 ++ 32 files changed, 775 insertions(+), 246 deletions(-) create mode 100644 cibuildwheel/resources/android/fortran_shim.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 88b5bad8..579de065 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -39,7 +39,6 @@ repos: - nox>=2025.2.9 - orjson - packaging - - pyelftools - pygithub - pytest - rich diff --git a/README.md b/README.md index 1c88168a..9a98ad72 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,7 @@ The following diagram summarises the steps that cibuildwheel takes on each platf | | [`before-all`](https://cibuildwheel.pypa.io/en/stable/options/#before-all) | Execute a shell command on the build system before any wheels are built. | | | [`before-build`](https://cibuildwheel.pypa.io/en/stable/options/#before-build) | Execute a shell command preparing each wheel's build | | | [`xbuild-tools`](https://cibuildwheel.pypa.io/en/stable/options/#xbuild-tools) | Binaries on the path that should be included in an isolated cross-build environment. | +| | [`xbuild-files`](https://cibuildwheel.pypa.io/en/stable/options/#xbuild-files) | Platform-specific files in the build environment | | | [`repair-wheel-command`](https://cibuildwheel.pypa.io/en/stable/options/#repair-wheel-command) | Execute a shell command to repair each built wheel | | | [`manylinux-*-image`
`musllinux-*-image`](https://cibuildwheel.pypa.io/en/stable/options/#linux-image) | Specify manylinux / musllinux container images | | | [`container-engine`](https://cibuildwheel.pypa.io/en/stable/options/#container-engine) | Specify the container engine to use when building Linux wheels | @@ -173,7 +174,7 @@ The following diagram summarises the steps that cibuildwheel takes on each platf | | [`build-verbosity`](https://cibuildwheel.pypa.io/en/stable/options/#build-verbosity) | Increase/decrease the output of the build | - + These options can be specified in a pyproject.toml file, or as environment variables, see [configuration docs](https://cibuildwheel.pypa.io/en/latest/configuration/). diff --git a/bin/generate_schema.py b/bin/generate_schema.py index 59654d70..a7d37162 100755 --- a/bin/generate_schema.py +++ b/bin/generate_schema.py @@ -15,6 +15,8 @@ parser = argparse.ArgumentParser(allow_abbrev=False) parser.add_argument("--schemastore", action="store_true", help="Generate schema_store version") args = parser.parse_args() +# The defaults in the schema are used by external tools for validation and IDE support. They +# should match the values in defaults.toml, which are used by cibuildwheel itself. starter = """ $schema: http://json-schema.org/draft-07/schema# $id: https://github.com/pypa/cibuildwheel/blob/main/cibuildwheel/resources/cibuildwheel.schema.json @@ -200,6 +202,9 @@ properties: xbuild-tools: description: Binaries on the path that should be included in an isolated cross-build environment type: string_array + xbuild-files: + description: Platform-specific files in the build environment + type: string_table_array pyodide-version: type: string description: Specify the version of Pyodide to use @@ -319,6 +324,7 @@ items: before-all: {"$ref": "#/$defs/inherit"} before-build: {"$ref": "#/$defs/inherit"} xbuild-tools: {"$ref": "#/$defs/inherit"} + xbuild-files: {"$ref": "#/$defs/inherit"} before-test: {"$ref": "#/$defs/inherit"} config-settings: {"$ref": "#/$defs/inherit"} container-engine: {"$ref": "#/$defs/inherit"} @@ -374,14 +380,15 @@ oses = { "ios": as_object(not_linux), } -oses["linux"]["properties"]["repair-wheel-command"] = { - **schema["properties"]["repair-wheel-command"], - "default": "auditwheel repair -w {dest_dir} {wheel}", -} -oses["macos"]["properties"]["repair-wheel-command"] = { - **schema["properties"]["repair-wheel-command"], - "default": "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}", -} +for os_name, command in [ + ("linux", "auditwheel repair -w {dest_dir} {wheel}"), + ("macos", "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}"), + ("android", "auditwheel repair --ldpaths {ldpaths} -w {dest_dir} {wheel}"), +]: + oses[os_name]["properties"]["repair-wheel-command"] = { + **schema["properties"]["repair-wheel-command"], + "default": command, + } del oses["linux"]["properties"]["dependency-versions"] diff --git a/bin/run_example_ci_configs.py b/bin/run_example_ci_configs.py index fbc392f8..90287f5b 100755 --- a/bin/run_example_ci_configs.py +++ b/bin/run_example_ci_configs.py @@ -3,6 +3,7 @@ # /// script # dependencies = [ # "click", +# "jinja2", # ] # /// @@ -39,13 +40,16 @@ def generate_project(path: Path, build_backend: BuildBackend) -> None: sys.path.insert(0, "") match build_backend: case "meson": - from test.test_projects.meson import new_meson_project as new_project # noqa: PLC0415 + from test.test_projects.meson import new_meson_project # noqa: PLC0415 + + project = new_meson_project() case "setuptools": - from test.test_projects.setuptools import new_c_project as new_project # noqa: PLC0415 + from test.test_projects.setuptools import new_c_project # noqa: PLC0415 + + project = new_c_project() case _: typing.assert_never(build_backend) - project = new_project() project.generate(path) diff --git a/cibuildwheel/options.py b/cibuildwheel/options.py index 89b64681..20607e5c 100644 --- a/cibuildwheel/options.py +++ b/cibuildwheel/options.py @@ -120,6 +120,7 @@ class BuildOptions: before_all: str before_build: str | None xbuild_tools: list[str] | None + xbuild_files: dict[str, list[str]] repair_command: str manylinux_images: dict[str, str] | None musllinux_images: dict[str, str] | None @@ -772,6 +773,14 @@ class Options: if xbuild_tools == ["\u0000"]: xbuild_tools = None + xbuild_files = parse_key_value_string( + self.reader.get( + "xbuild-files", + option_format=ShlexTableFormat(sep="; ", pair_sep=":", allow_merge=False), + ), + kw_arg_names=["*"], + ) + test_sources = shlex.split( self.reader.get( "test-sources", option_format=ListFormat(sep=" ", quote=shlex.quote) @@ -925,6 +934,7 @@ class Options: before_all=before_all, build_verbosity=build_verbosity, xbuild_tools=xbuild_tools, + xbuild_files=xbuild_files, repair_command=repair_command, environment=environment, dependency_constraints=dependency_constraints, diff --git a/cibuildwheel/platforms/android.py b/cibuildwheel/platforms/android.py index b8bd4bf5..59c3869f 100644 --- a/cibuildwheel/platforms/android.py +++ b/cibuildwheel/platforms/android.py @@ -1,16 +1,13 @@ from __future__ import annotations -import csv -import hashlib import os import platform import re import shlex import shutil import subprocess -import sysconfig +import sys from dataclasses import dataclass -from os.path import relpath from pathlib import Path from pprint import pprint from runpy import run_path @@ -19,9 +16,8 @@ from typing import Any from build import ProjectBuilder from build.env import IsolatedEnv -from elftools.common.exceptions import ELFError -from elftools.elf.elffile import ELFFile from filelock import FileLock +from packaging.utils import canonicalize_name from cibuildwheel import errors, platforms # pylint: disable=cyclic-import from cibuildwheel.architecture import Architecture, arch_synonym @@ -42,10 +38,9 @@ from cibuildwheel.venv import constraint_flags, find_uv, virtualenv TYPE_CHECKING = False if TYPE_CHECKING: - from collections.abc import Iterable, Iterator, MutableMapping - from cibuildwheel.options import BuildOptions, Options from cibuildwheel.selector import BuildSelector + from cibuildwheel.typing import PathOrStr RESOURCES_ANDROID = resources.PATH / "android" ANDROID_TRIPLET = { @@ -148,6 +143,7 @@ def build(options: Options, tmp_path: Path) -> None: state = BuildState( config, build_options, build_path, python_dir, build_env, android_env ) + setup_xbuild_files(state) compatible_wheel = find_compatible_wheel(built_wheels, config.identifier) if compatible_wheel: @@ -162,7 +158,7 @@ def build(options: Options, tmp_path: Path) -> None: repaired_wheel = repair_wheel(state, built_wheel) run_audit(tmp_dir=tmp_path, build_options=build_options, wheel=repaired_wheel) - test_wheel(state, repaired_wheel, build_frontend=build_options.build_frontend.name) + test_wheel(state, repaired_wheel) output_wheel: Path | None = None if compatible_wheel is None: @@ -194,6 +190,11 @@ def setup_target_python(config: PythonConfiguration, build_path: Path) -> Path: # updated to Python versions that include the fix. call("patch", "-p1", "-i", RESOURCES_ANDROID / "android.patch", cwd=python_dir) + # Work around https://github.com/python/cpython/issues/138800. This can be removed + # once we've updated to Python versions that include the fix. + pc_path = python_dir / f"prefix/lib/pkgconfig/python-{config.version}.pc" + pc_path.write_text(pc_path.read_text().replace("$(BLDLIBRARY)", f"-lpython{config.version}")) + return python_dir @@ -207,13 +208,7 @@ def setup_env( * android_env, which uses the environment while simulating running on Android. """ log.step("Setting up build environment...") - build_frontend = build_options.build_frontend.name - use_uv = build_frontend in {"build[uv]", "uv"} - uv_path = find_uv() - if use_uv and uv_path is None: - msg = "uv not found" - raise AssertionError(msg) - pip = ["pip"] if not use_uv else [str(uv_path), "pip"] + use_uv, pip = find_pip(build_options) # Create virtual environment python_exe = create_python_build_standalone_environment( @@ -228,6 +223,9 @@ def setup_env( ) create_cmake_toolchain(config, build_path, python_dir, build_env) + # See platforms.md for the reason why we use this default API level. + build_env.setdefault("ANDROID_API_LEVEL", "24") + # Apply custom environment variables, and check environment is still valid build_env = build_options.environment.as_dictionary(build_env) build_env["PIP_DISABLE_PIP_VERSION_CHECK"] = "1" @@ -245,14 +243,14 @@ def setup_env( else: call(command, "--version", env=build_env) - # Construct an altered environment which simulates running on Android. - android_env = setup_android_env(config, python_dir, venv_dir, build_env) - # Install build tools - if build_frontend not in {"build", "build[uv]", "uv"}: - msg = "Android requires the build frontend to be 'build' or 'uv'" - raise errors.FatalError(msg) - call(*pip, "install", "build", *constraint_flags(dependency_constraint), env=build_env) + tools = ["auditwheel", "patchelf", "pkgconf"] + if build_options.build_frontend.name in {"build", "build[uv]"}: + tools.append("build") + call(*pip, "install", *tools, *constraint_flags(dependency_constraint), env=build_env) + + # Construct an altered environment which simulates running on Android. + android_env = setup_android_env(config, python_dir, build_env) # Build-time requirements must be queried within android_env, because # `get_requires_for_build` can run arbitrary code in setup.py scripts, which may be @@ -343,8 +341,7 @@ def localized_vars( final = final.replace(orig_prefix, str(prefix)) if key == "ANDROID_API_LEVEL": - if api_level := build_env.get(key): - final = int(api_level) + final = int(build_env[key]) # Build systems vary in whether FLAGS variables are read from sysconfig, and if so, # whether they're replaced by environment variables or combined with them. Even @@ -367,15 +364,15 @@ def localized_vars( def setup_android_env( - config: PythonConfiguration, python_dir: Path, venv_dir: Path, build_env: dict[str, str] + config: PythonConfiguration, python_dir: Path, build_env: dict[str, str] ) -> dict[str, str]: - site_packages = next(venv_dir.glob("lib/python*/site-packages")) + site_packages = find_site_packages(build_env) for suffix in ["pth", "py"]: shutil.copy(RESOURCES_ANDROID / f"_cross_venv.{suffix}", site_packages) sysconfigdata_path = Path( shutil.copy( - next(python_dir.glob("prefix/lib/python*/_sysconfigdata_*.py")), + glob1(python_dir, "prefix/lib/python*/_sysconfigdata_*.py"), site_packages, ) ) @@ -414,6 +411,17 @@ def setup_android_env( # Cargo target linker needs to be specified after CC is set setup_rust(config, python_dir, android_env) + # Create shims which install additional build tools on first use. + setup_fortran(android_env) + + # `android.py env` returns PKG_CONFIG="pkg-config --define-prefix", but some build + # systems can't handle arguments in that variable. Since we have a known version + # of pkgconf, it's safe to use PKG_CONFIG_RELOCATE_PATHS instead. + android_env["PKG_CONFIG"] = call( + "which", "pkgconf-pypi", env=build_env, capture_stdout=True + ).strip() + android_env["PKG_CONFIG_RELOCATE_PATHS"] = "1" + # Format the environment so it can be pasted into a shell when debugging. for key, value in sorted(android_env.items()): if os.environ.get(key) != value: @@ -422,11 +430,7 @@ def setup_android_env( return android_env -def setup_rust( - config: PythonConfiguration, - python_dir: Path, - env: MutableMapping[str, str], -) -> None: +def setup_rust(config: PythonConfiguration, python_dir: Path, env: dict[str, str]) -> None: cargo_target = android_triplet(config.identifier) # CARGO_BUILD_TARGET is the variable used by Cargo and setuptools_rust @@ -450,13 +454,83 @@ def setup_rust( shim_path.chmod(0o755) +def setup_fortran(env: dict[str, str]) -> None: + # In case there's any autodetection based on the executable name, use the same name + # as the real executable (see fortran_shim.run_flang) + shim_in = RESOURCES_ANDROID / "fortran_shim.py" + shim_out = Path(env["VIRTUAL_ENV"]) / "bin/flang-new" + + # The hashbang line runs the shim in cibuildwheel's own virtual environment, so it + # has access to utility functions for downloading and caching files. + shim_out.write_text(f"#!{sys.executable}\n\n" + shim_in.read_text()) + shim_out.chmod(0o755) + env["FC"] = str(shim_out) + + +def setup_xbuild_files(state: BuildState) -> None: + _, pip = find_pip(state.options) + xbf_dir = state.build_path / "xbuild_files" + xbf_dir.mkdir() + + for requirement in call(*pip, "freeze", env=state.build_env, capture_stdout=True).splitlines(): + name, _, _ = requirement.strip().partition("==") + xbuild_files = state.options.xbuild_files.get(canonicalize_name(name), []) + if xbuild_files: + log.step(f"Installing xbuild-files for {name}...") + pip_install_android(state, xbf_dir, "--no-deps", requirement) + for xbf in xbuild_files: + if (xbf_dir / xbf).exists(): + shutil.copy( + xbf_dir / xbf, + find_site_packages(state.build_env) / xbf, + ) + else: + log.warning(f"{xbf_dir / xbf} does not exist") + + +def pip_install_android(state: BuildState, target: Path, *args: PathOrStr) -> None: + use_uv, pip = find_pip(state.options) + call( + *pip, + "install", + "--only-binary=:all:", + *(["--python-platform", android_triplet(state.config.identifier)] if use_uv else []), + "--target", + target, + *args, + env=state.android_env, + ) + + +def find_site_packages(env: dict[str, str]) -> Path: + return glob1(Path(env["VIRTUAL_ENV"]), "lib/python*/site-packages") + + +def glob1(base: Path, pattern: str) -> Path: + results = list(base.glob(pattern)) + if len(results) != 1: + msg = f"{base} contains {len(results)} paths matching '{pattern}'; expected 1" + raise errors.FatalError(msg) + return results[0] + + +def find_pip(build_options: BuildOptions) -> tuple[bool, list[str]]: + use_uv = build_options.build_frontend.name in {"build[uv]", "uv"} + uv_path = find_uv() + if use_uv and uv_path is None: + msg = "uv not found" + raise AssertionError(msg) + pip = ["pip"] if not use_uv else [str(uv_path), "pip"] + return use_uv, pip + + def before_build(state: BuildState) -> None: if state.options.before_build: log.step("Running before_build...") shell_prepared( state.options.before_build, build_options=state.options, - env=state.build_env, + env=state.android_env, ) @@ -507,15 +581,10 @@ def build_wheel(state: BuildState) -> Path: env=state.android_env, ) case x: - msg = f"Invalid build backend {x!r}" - raise AssertionError(msg) - - built_wheels = list(built_wheel_dir.glob("*.whl")) - if len(built_wheels) != 1: - msg = f"{built_wheel_dir} contains {len(built_wheels)} wheels; expected 1" - raise errors.FatalError(msg) - built_wheel = built_wheels[0] + msg = f"Android requires the build frontend to be 'build' or 'uv', not {x!r}" + raise errors.FatalError(msg) + built_wheel = glob1(built_wheel_dir, "*.whl") if built_wheel.name.endswith("none-any.whl"): raise errors.NonPlatformWheelError() return built_wheel @@ -527,9 +596,20 @@ def repair_wheel(state: BuildState, built_wheel: Path) -> Path: repaired_wheel_dir.mkdir() if state.options.repair_command: + # Tell auditwheel the locations of compiler libraries. + toolchain = Path(state.android_env["CC"]).parent.parent + triplet = android_triplet(state.config.identifier) + ldpaths = ":".join( + str(glob1(toolchain, pattern)) + for pattern in [ + f"lib/clang/*/lib/linux/{triplet.split('-')[0]}", # libomp + f"sysroot/usr/lib/{triplet}", # libc++_shared + ] + ) shell( prepare_command( state.options.repair_command, + ldpaths=ldpaths, wheel=built_wheel, dest_dir=repaired_wheel_dir, package=state.options.package_dir, @@ -538,14 +618,15 @@ def repair_wheel(state: BuildState, built_wheel: Path) -> Path: env=state.build_env, ) else: - repair_default(state.android_env, built_wheel, repaired_wheel_dir) + shutil.move(built_wheel, repaired_wheel_dir) repaired_wheels = list(repaired_wheel_dir.glob("*.whl")) if len(repaired_wheels) == 0: raise errors.RepairStepProducedNoWheelError() if len(repaired_wheels) != 1: - msg = f"{repaired_wheel_dir} contains {len(repaired_wheels)} wheels; expected 1" - raise errors.FatalError(msg) + raise errors.RepairStepProducedMultipleWheelsError( + [rw.name for rw in repaired_wheels], + ) repaired_wheel = repaired_wheels[0] if repaired_wheel.name.endswith("none-any.whl"): @@ -553,119 +634,12 @@ def repair_wheel(state: BuildState, built_wheel: Path) -> Path: return repaired_wheel -def repair_default( - android_env: dict[str, str], built_wheel: Path, repaired_wheel_dir: Path -) -> None: - """ - Adds libc++ to the wheel if anything links against it. In the future this should be - moved to auditwheel and generalized to support more libraries. - """ - if (match := re.search(r"^(.+?)-", built_wheel.name)) is None: - msg = f"Failed to parse wheel filename: {built_wheel.name}" - raise errors.FatalError(msg) - wheel_name = match[1] - - unpacked_dir = repaired_wheel_dir / "unpacked" - unpacked_dir.mkdir() - shutil.unpack_archive(built_wheel, unpacked_dir, format="zip") - - # Some build systems are inconsistent about name normalization, so don't assume the - # dist-info name is identical to the wheel name. - record_paths = list(unpacked_dir.glob("*.dist-info/RECORD")) - if len(record_paths) != 1: - msg = f"{built_wheel.name} contains {len(record_paths)} dist-info/RECORD files; expected 1" - raise errors.FatalError(msg) - - old_soname = "libc++_shared.so" - paths_to_patch = [] - for path, elffile in elf_file_filter( - unpacked_dir / filename - for filename, *_ in csv.reader(record_paths[0].read_text().splitlines()) - ): - if (dynamic := elffile.get_section_by_name(".dynamic")) and any( # type: ignore[no-untyped-call] - tag.entry.d_tag == "DT_NEEDED" and tag.needed == old_soname - for tag in dynamic.iter_tags() - ): - paths_to_patch.append(path) - - if not paths_to_patch: - shutil.copyfile(built_wheel, repaired_wheel_dir / built_wheel.name) - else: - # Android doesn't support DT_RPATH, but supports DT_RUNPATH since API level 24 - # (https://github.com/aosp-mirror/platform_bionic/blob/master/android-changes-for-ndk-developers.md). - if int(sysconfig_print('get_config_vars()["ANDROID_API_LEVEL"]', android_env)) < 24: - msg = f"Adding {old_soname} requires ANDROID_API_LEVEL to be at least 24" - raise errors.FatalError(msg) - - toolchain = Path(android_env["CC"]).parent.parent - src_path = toolchain / f"sysroot/usr/lib/{android_env['CIBW_HOST_TRIPLET']}/{old_soname}" - - # Use the same library location as auditwheel would. - libs_dir = unpacked_dir / (wheel_name + ".libs") - libs_dir.mkdir() - new_soname = soname_with_hash(src_path) - dst_path = libs_dir / new_soname - shutil.copyfile(src_path, dst_path) - call(which("patchelf"), "--set-soname", new_soname, dst_path) - - for path in paths_to_patch: - call(which("patchelf"), "--replace-needed", old_soname, new_soname, path) - call( - which("patchelf"), - "--set-rpath", - f"${{ORIGIN}}/{relpath(libs_dir, path.parent)}", - path, - ) - call(which("wheel"), "pack", unpacked_dir, "-d", repaired_wheel_dir) - - -# If cibuildwheel was called without activating its environment, its scripts directory -# will not be on the PATH. -def which(cmd: str) -> str: - scripts_dir = sysconfig.get_path("scripts") - result = shutil.which(cmd, path=scripts_dir + os.pathsep + os.environ["PATH"]) - if result is None: - msg = f"Couldn't find {cmd!r} in {scripts_dir} or on the PATH" - raise errors.FatalError(msg) - return result - - -def elf_file_filter(paths: Iterable[Path]) -> Iterator[tuple[Path, ELFFile]]: - """Filter through an iterator of filenames and load up only ELF files""" - for path in paths: - if not path.name.endswith(".py"): - try: - with open(path, "rb") as f: - candidate = ELFFile(f) # type: ignore[no-untyped-call] - yield path, candidate - except ELFError: - pass # Not an ELF file - - -def soname_with_hash(src_path: Path) -> str: - """Return the same library filename as auditwheel would""" - shorthash = hashlib.sha256(src_path.read_bytes()).hexdigest()[:8] - src_name = src_path.name - base, ext = src_name.split(".", 1) - if not base.endswith(f"-{shorthash}"): - return f"{base}-{shorthash}.{ext}" - else: - return src_name - - -def test_wheel(state: BuildState, wheel: Path, *, build_frontend: str) -> None: +def test_wheel(state: BuildState, wheel: Path) -> None: test_command = state.options.test_command if not (test_command and state.options.test_selector(state.config.identifier)): return log.step("Testing wheel...") - use_uv = build_frontend in {"build[uv]", "uv"} - uv_path = find_uv() - if use_uv and uv_path is None: - msg = "uv not found" - raise AssertionError(msg) - pip = ["pip"] if not use_uv else [str(uv_path), "pip"] - native_arch = arch_synonym(platform.machine(), platforms.native_platform(), "android") if state.config.arch != native_arch: log.warning( @@ -678,31 +652,17 @@ def test_wheel(state: BuildState, wheel: Path, *, build_frontend: str) -> None: shell_prepared( state.options.before_test, build_options=state.options, - env=state.build_env, + env=state.android_env, ) - platform_args = ( - ["--python-platform", android_triplet(state.config.identifier)] - if use_uv - else [ - "--platform", - sysconfig_print("get_platform()", state.android_env).replace("-", "_"), - ] - ) - # Install the wheel and test-requires. site_packages_dir = state.build_path / "site-packages" site_packages_dir.mkdir() - call( - *pip, - "install", - "--only-binary=:all:", - *platform_args, - "--target", + pip_install_android( + state, site_packages_dir, f"{wheel}{state.options.test_extras}", *state.options.test_requires, - env=state.android_env, ) # Copy test-sources. @@ -772,13 +732,3 @@ def test_wheel(state: BuildState, wheel: Path, *, build_frontend: str) -> None: *test_args, env=state.build_env, ) - - -def sysconfig_print(method_call: str, env: dict[str, str]) -> str: - return call( - "python", - "-c", - f'import sysconfig; print(sysconfig.{method_call}, end="")', - env=env, - capture_stdout=True, - ) diff --git a/cibuildwheel/resources/android/_cross_venv.py b/cibuildwheel/resources/android/_cross_venv.py index 40dfaca5..0c50dcce 100644 --- a/cibuildwheel/resources/android/_cross_venv.py +++ b/cibuildwheel/resources/android/_cross_venv.py @@ -14,6 +14,9 @@ def initialize() -> None: if not (host_triplet := os.environ.get("CIBW_HOST_TRIPLET")): return + # Pre-import any modules which would fail to import after the monkey-patching. + import ctypes # noqa: F401, PLC0415 - uses get_config_var("LDLIBRARY") + # os ###################################################################### def cross_os_uname() -> os.uname_result: return os.uname_result( diff --git a/cibuildwheel/resources/android/fortran_shim.py b/cibuildwheel/resources/android/fortran_shim.py new file mode 100644 index 00000000..f91b55ba --- /dev/null +++ b/cibuildwheel/resources/android/fortran_shim.py @@ -0,0 +1,121 @@ +# This file intentionally has no hashbang line in the source: cibuildwheel will add it +# above this comment when the file is deployed. + +import os +import re +import shutil +import sys +from pathlib import Path +from tempfile import gettempdir + +from filelock import FileLock + +from cibuildwheel.util.file import CIBW_CACHE_PATH, download + +# In the future we might pick a different Flang release depending on the NDK version, +# but so far all Python versions use the same NDK version, so there's no need. +RELEASE_URL = "https://github.com/termux/ndk-toolchain-clang-with-flang/releases/download" +RELEASE_VERSION = "r27c" +ARCHS = ["aarch64", "x86_64"] + +# The compiler is built for Linux x86_64, so we use Docker on macOS. +DOCKER_IMAGE = "debian:trixie-slim" + + +def main() -> None: + cache_dir = CIBW_CACHE_PATH / f"flang-android-{RELEASE_VERSION}" + with FileLock(f"{cache_dir}.lock"): + if not cache_dir.exists(): + download_flang(cache_dir) + + run_flang(cache_dir) + + +def download_flang(cache_dir: Path) -> None: + tmp_dir = Path(f"{cache_dir}.tmp") + if tmp_dir.exists(): + shutil.rmtree(tmp_dir) + tmp_dir.mkdir(parents=True) + + for archive_name in [f"package-flang-{arch}.tar.bz2" for arch in ARCHS] + [ + "package-flang-host.tar.bz2", + "package-install.tar.bz2", + ]: + archive_path = tmp_dir / archive_name + download(f"{RELEASE_URL}/{RELEASE_VERSION}/{archive_name}", archive_path) + shutil.unpack_archive(archive_path, tmp_dir) + archive_path.unlink() + + # Merge the extracted trees together, along with the necessary parts of the NDK. Based on + # https://github.com/kivy/python-for-android/blob/develop/pythonforandroid/recipes/fortran/__init__.py. + flang_toolchain = tmp_dir / "toolchain" + (tmp_dir / "out/install/linux-x86/clang-dev").rename(flang_toolchain) + + ndk_toolchain = Path(os.environ["CC"]).parents[1] + if (clang_ver_flang := clang_ver(flang_toolchain)) != ( + clang_ver_ndk := clang_ver(ndk_toolchain) + ): + msg = f"Flang uses Clang {clang_ver_flang}, but NDK uses Clang {clang_ver_ndk}" + raise ValueError(msg) + + clang_lib_path = f"lib/clang/{clang_ver_ndk}/lib" + shutil.rmtree(flang_toolchain / clang_lib_path) + + for src, dst in [ + (f"{tmp_dir}/build-{arch}-install", f"sysroot/usr/lib/{arch}-linux-android") + for arch in ARCHS + ] + [ + (f"{tmp_dir}/build-host-install", ""), + (f"{ndk_toolchain}/{clang_lib_path}", clang_lib_path), + (f"{ndk_toolchain}/sysroot", "sysroot"), + ]: + shutil.copytree(src, flang_toolchain / dst, symlinks=True, dirs_exist_ok=True) + + flang_toolchain.rename(cache_dir) + shutil.rmtree(tmp_dir) + + +def clang_ver(toolchain: Path) -> str: + versions = [p.name for p in (toolchain / "lib/clang").iterdir()] + assert len(versions) == 1 + return versions[0] + + +def run_flang(cache_dir: Path) -> None: + match = re.fullmatch(r".+/(.+)-clang", os.environ["CC"]) + assert match is not None + target = match[1] + + # In a future Flang version the executable name will change to "flang" + # (https://blog.llvm.org/posts/2025-03-11-flang-new/). + flang_args = [f"{cache_dir}/bin/flang-new", f"--target={target}", *sys.argv[1:]] + + if sys.platform == "linux": + args = flang_args + elif sys.platform == "darwin": + args = ["docker", "run", "--rm", "--platform", "linux/amd64"] + # Docker on macOS only allows certain directories to be mounted as volumes + # by default, but they include all the locations we're likely to need. + for path in [ + # Location of CIBW_CACHE_PATH (containing the Fortran compiler), and + # probably the project directory. + Path.home(), + # Temporary directories created by build backends and cibuildwheel itself. + # This is controlled by the TMPDIR environment variable, which is set to + # an unpredictable subdirectory of /var/folders. /var is itself a symlink + # to /private/var. + Path(gettempdir()), + Path(gettempdir()).resolve(), + ]: + args += ["-v", f"{path}:{path}"] + args += ["--workdir", str(Path.cwd())] + args += ["--entrypoint", flang_args[0], DOCKER_IMAGE, *flang_args[1:]] + else: + msg = f"unknown platform: {sys.platform}" + raise ValueError(msg) + + os.execvp(args[0], args) + + +if __name__ == "__main__": + main() diff --git a/cibuildwheel/resources/cibuildwheel.schema.json b/cibuildwheel/resources/cibuildwheel.schema.json index 7d2522a6..707940d9 100644 --- a/cibuildwheel/resources/cibuildwheel.schema.json +++ b/cibuildwheel/resources/cibuildwheel.schema.json @@ -460,6 +460,34 @@ ], "title": "CIBW_XBUILD_TOOLS" }, + "xbuild-files": { + "description": "Platform-specific files in the build environment", + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "additionalProperties": false, + "patternProperties": { + ".+": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + } + } + } + ], + "title": "CIBW_XBUILD_FILES" + }, "pyodide-version": { "type": "string", "description": "Specify the version of Pyodide to use", @@ -679,6 +707,9 @@ "xbuild-tools": { "$ref": "#/$defs/inherit" }, + "xbuild-files": { + "$ref": "#/$defs/inherit" + }, "before-test": { "$ref": "#/$defs/inherit" }, @@ -807,6 +838,9 @@ "xbuild-tools": { "$ref": "#/properties/xbuild-tools" }, + "xbuild-files": { + "$ref": "#/properties/xbuild-files" + }, "pyodide-version": { "$ref": "#/properties/pyodide-version" }, @@ -931,6 +965,9 @@ "xbuild-tools": { "$ref": "#/properties/xbuild-tools" }, + "xbuild-files": { + "$ref": "#/properties/xbuild-files" + }, "pyodide-version": { "$ref": "#/properties/pyodide-version" }, @@ -1013,6 +1050,9 @@ "xbuild-tools": { "$ref": "#/properties/xbuild-tools" }, + "xbuild-files": { + "$ref": "#/properties/xbuild-files" + }, "pyodide-version": { "$ref": "#/properties/pyodide-version" }, @@ -1082,6 +1122,9 @@ "xbuild-tools": { "$ref": "#/properties/xbuild-tools" }, + "xbuild-files": { + "$ref": "#/properties/xbuild-files" + }, "pyodide-version": { "$ref": "#/properties/pyodide-version" }, @@ -1164,6 +1207,9 @@ "xbuild-tools": { "$ref": "#/properties/xbuild-tools" }, + "xbuild-files": { + "$ref": "#/properties/xbuild-files" + }, "pyodide-version": { "$ref": "#/properties/pyodide-version" }, @@ -1233,11 +1279,27 @@ "xbuild-tools": { "$ref": "#/properties/xbuild-tools" }, + "xbuild-files": { + "$ref": "#/properties/xbuild-files" + }, "pyodide-version": { "$ref": "#/properties/pyodide-version" }, "repair-wheel-command": { - "$ref": "#/properties/repair-wheel-command" + "description": "Execute a shell command to repair each built wheel.", + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "title": "CIBW_REPAIR_WHEEL_COMMAND", + "default": "auditwheel repair --ldpaths {ldpaths} -w {dest_dir} {wheel}" }, "test-command": { "$ref": "#/properties/test-command" @@ -1302,6 +1364,9 @@ "xbuild-tools": { "$ref": "#/properties/xbuild-tools" }, + "xbuild-files": { + "$ref": "#/properties/xbuild-files" + }, "pyodide-version": { "$ref": "#/properties/pyodide-version" }, diff --git a/cibuildwheel/resources/constraints-python310.txt b/cibuildwheel/resources/constraints-python310.txt index 302967a6..8257343b 100644 --- a/cibuildwheel/resources/constraints-python310.txt +++ b/cibuildwheel/resources/constraints-python310.txt @@ -10,6 +10,8 @@ attrs==26.1.0 # via # cattrs # requests-cache +auditwheel==6.7.0 + # via -r cibuildwheel/resources/constraints.in build==1.5.0 # via -r cibuildwheel/resources/constraints.in cattrs==26.1.0 @@ -47,21 +49,28 @@ mdurl==0.1.2 packaging==26.2 # via # abi3audit + # auditwheel # build # delocate +patchelf==0.17.2.4 + # via -r cibuildwheel/resources/constraints.in pefile==2024.8.26 # via # abi3audit # delvewheel pip==26.1.1 # via -r cibuildwheel/resources/constraints.in +pkgconf==2.5.1.post2 + # via -r cibuildwheel/resources/constraints.in platformdirs==4.9.6 # via # python-discovery # requests-cache # virtualenv pyelftools==0.32 - # via abi3audit + # via + # abi3audit + # auditwheel pygments==2.20.0 # via rich pyproject-hooks==1.2.0 diff --git a/cibuildwheel/resources/constraints-python311.txt b/cibuildwheel/resources/constraints-python311.txt index edb93120..b3e5128d 100644 --- a/cibuildwheel/resources/constraints-python311.txt +++ b/cibuildwheel/resources/constraints-python311.txt @@ -10,6 +10,8 @@ attrs==26.1.0 # via # cattrs # requests-cache +auditwheel==6.7.0 + # via -r cibuildwheel/resources/constraints.in build==1.5.0 # via -r cibuildwheel/resources/constraints.in cattrs==26.1.0 @@ -43,8 +45,11 @@ mdurl==0.1.2 packaging==26.2 # via # abi3audit + # auditwheel # build # delocate +patchelf==0.17.2.4 + # via -r cibuildwheel/resources/constraints.in pefile==2024.8.26 # via # abi3audit @@ -52,13 +57,17 @@ pefile==2024.8.26 pip==26.1.1; implementation_name != "graalpy" or platform_system != "Windows" pip==26.0.1; implementation_name == "graalpy" and platform_system == "Windows" # via -r cibuildwheel/resources/constraints.in +pkgconf==2.5.1.post2 + # via -r cibuildwheel/resources/constraints.in platformdirs==4.9.6 # via # python-discovery # requests-cache # virtualenv pyelftools==0.32 - # via abi3audit + # via + # abi3audit + # auditwheel pygments==2.20.0 # via rich pyproject-hooks==1.2.0 diff --git a/cibuildwheel/resources/constraints-python312.txt b/cibuildwheel/resources/constraints-python312.txt index edb93120..b3e5128d 100644 --- a/cibuildwheel/resources/constraints-python312.txt +++ b/cibuildwheel/resources/constraints-python312.txt @@ -10,6 +10,8 @@ attrs==26.1.0 # via # cattrs # requests-cache +auditwheel==6.7.0 + # via -r cibuildwheel/resources/constraints.in build==1.5.0 # via -r cibuildwheel/resources/constraints.in cattrs==26.1.0 @@ -43,8 +45,11 @@ mdurl==0.1.2 packaging==26.2 # via # abi3audit + # auditwheel # build # delocate +patchelf==0.17.2.4 + # via -r cibuildwheel/resources/constraints.in pefile==2024.8.26 # via # abi3audit @@ -52,13 +57,17 @@ pefile==2024.8.26 pip==26.1.1; implementation_name != "graalpy" or platform_system != "Windows" pip==26.0.1; implementation_name == "graalpy" and platform_system == "Windows" # via -r cibuildwheel/resources/constraints.in +pkgconf==2.5.1.post2 + # via -r cibuildwheel/resources/constraints.in platformdirs==4.9.6 # via # python-discovery # requests-cache # virtualenv pyelftools==0.32 - # via abi3audit + # via + # abi3audit + # auditwheel pygments==2.20.0 # via rich pyproject-hooks==1.2.0 diff --git a/cibuildwheel/resources/constraints-python313.txt b/cibuildwheel/resources/constraints-python313.txt index 319dfcf5..9acfd1b6 100644 --- a/cibuildwheel/resources/constraints-python313.txt +++ b/cibuildwheel/resources/constraints-python313.txt @@ -10,6 +10,8 @@ attrs==26.1.0 # via # cattrs # requests-cache +auditwheel==6.7.0 + # via -r cibuildwheel/resources/constraints.in build==1.5.0 # via -r cibuildwheel/resources/constraints.in cattrs==26.1.0 @@ -43,21 +45,28 @@ mdurl==0.1.2 packaging==26.2 # via # abi3audit + # auditwheel # build # delocate +patchelf==0.17.2.4 + # via -r cibuildwheel/resources/constraints.in pefile==2024.8.26 # via # abi3audit # delvewheel pip==26.1.1 # via -r cibuildwheel/resources/constraints.in +pkgconf==2.5.1.post2 + # via -r cibuildwheel/resources/constraints.in platformdirs==4.9.6 # via # python-discovery # requests-cache # virtualenv pyelftools==0.32 - # via abi3audit + # via + # abi3audit + # auditwheel pygments==2.20.0 # via rich pyproject-hooks==1.2.0 diff --git a/cibuildwheel/resources/constraints-python314.txt b/cibuildwheel/resources/constraints-python314.txt index 319dfcf5..9acfd1b6 100644 --- a/cibuildwheel/resources/constraints-python314.txt +++ b/cibuildwheel/resources/constraints-python314.txt @@ -10,6 +10,8 @@ attrs==26.1.0 # via # cattrs # requests-cache +auditwheel==6.7.0 + # via -r cibuildwheel/resources/constraints.in build==1.5.0 # via -r cibuildwheel/resources/constraints.in cattrs==26.1.0 @@ -43,21 +45,28 @@ mdurl==0.1.2 packaging==26.2 # via # abi3audit + # auditwheel # build # delocate +patchelf==0.17.2.4 + # via -r cibuildwheel/resources/constraints.in pefile==2024.8.26 # via # abi3audit # delvewheel pip==26.1.1 # via -r cibuildwheel/resources/constraints.in +pkgconf==2.5.1.post2 + # via -r cibuildwheel/resources/constraints.in platformdirs==4.9.6 # via # python-discovery # requests-cache # virtualenv pyelftools==0.32 - # via abi3audit + # via + # abi3audit + # auditwheel pygments==2.20.0 # via rich pyproject-hooks==1.2.0 diff --git a/cibuildwheel/resources/constraints-python315.txt b/cibuildwheel/resources/constraints-python315.txt index 319dfcf5..9acfd1b6 100644 --- a/cibuildwheel/resources/constraints-python315.txt +++ b/cibuildwheel/resources/constraints-python315.txt @@ -10,6 +10,8 @@ attrs==26.1.0 # via # cattrs # requests-cache +auditwheel==6.7.0 + # via -r cibuildwheel/resources/constraints.in build==1.5.0 # via -r cibuildwheel/resources/constraints.in cattrs==26.1.0 @@ -43,21 +45,28 @@ mdurl==0.1.2 packaging==26.2 # via # abi3audit + # auditwheel # build # delocate +patchelf==0.17.2.4 + # via -r cibuildwheel/resources/constraints.in pefile==2024.8.26 # via # abi3audit # delvewheel pip==26.1.1 # via -r cibuildwheel/resources/constraints.in +pkgconf==2.5.1.post2 + # via -r cibuildwheel/resources/constraints.in platformdirs==4.9.6 # via # python-discovery # requests-cache # virtualenv pyelftools==0.32 - # via abi3audit + # via + # abi3audit + # auditwheel pygments==2.20.0 # via rich pyproject-hooks==1.2.0 diff --git a/cibuildwheel/resources/constraints-python39.txt b/cibuildwheel/resources/constraints-python39.txt index 835292fa..95ee8285 100644 --- a/cibuildwheel/resources/constraints-python39.txt +++ b/cibuildwheel/resources/constraints-python39.txt @@ -10,6 +10,8 @@ attrs==26.1.0 # via # cattrs # requests-cache +auditwheel==6.4.2 + # via -r cibuildwheel/resources/constraints.in build==1.4.4 # via -r cibuildwheel/resources/constraints.in cattrs==25.3.0 @@ -35,7 +37,9 @@ idna==3.16 # requests # url-normalize importlib-metadata==8.7.1 - # via build + # via + # build + # pkgconf kaitaistruct==0.11 # via abi3audit macholib==1.16.4 @@ -47,21 +51,28 @@ mdurl==0.1.2 packaging==25.0 # via # abi3audit + # auditwheel # build # delocate +patchelf==0.17.2.4 + # via -r cibuildwheel/resources/constraints.in pefile==2024.8.26 # via # abi3audit # delvewheel pip==26.0.1 # via -r cibuildwheel/resources/constraints.in +pkgconf==2.4.3.post2 + # via -r cibuildwheel/resources/constraints.in platformdirs==4.4.0 # via # python-discovery # requests-cache # virtualenv pyelftools==0.32 - # via abi3audit + # via + # abi3audit + # auditwheel pygments==2.20.0 # via rich pyproject-hooks==1.2.0 diff --git a/cibuildwheel/resources/constraints.in b/cibuildwheel/resources/constraints.in index 72b0befd..3762c279 100644 --- a/cibuildwheel/resources/constraints.in +++ b/cibuildwheel/resources/constraints.in @@ -4,3 +4,8 @@ delocate delvewheel virtualenv abi3audit + +# Android +auditwheel +patchelf +pkgconf diff --git a/cibuildwheel/resources/constraints.txt b/cibuildwheel/resources/constraints.txt index 319dfcf5..9acfd1b6 100644 --- a/cibuildwheel/resources/constraints.txt +++ b/cibuildwheel/resources/constraints.txt @@ -10,6 +10,8 @@ attrs==26.1.0 # via # cattrs # requests-cache +auditwheel==6.7.0 + # via -r cibuildwheel/resources/constraints.in build==1.5.0 # via -r cibuildwheel/resources/constraints.in cattrs==26.1.0 @@ -43,21 +45,28 @@ mdurl==0.1.2 packaging==26.2 # via # abi3audit + # auditwheel # build # delocate +patchelf==0.17.2.4 + # via -r cibuildwheel/resources/constraints.in pefile==2024.8.26 # via # abi3audit # delvewheel pip==26.1.1 # via -r cibuildwheel/resources/constraints.in +pkgconf==2.5.1.post2 + # via -r cibuildwheel/resources/constraints.in platformdirs==4.9.6 # via # python-discovery # requests-cache # virtualenv pyelftools==0.32 - # via abi3audit + # via + # abi3audit + # auditwheel pygments==2.20.0 # via rich pyproject-hooks==1.2.0 diff --git a/cibuildwheel/resources/defaults.toml b/cibuildwheel/resources/defaults.toml index e0937490..0a46e945 100644 --- a/cibuildwheel/resources/defaults.toml +++ b/cibuildwheel/resources/defaults.toml @@ -1,3 +1,6 @@ +# These are the defaults used by cibuildwheel itself. They should match the values in +# generate_schema.py, which are used by external tools for validation and IDE support. + [tool.cibuildwheel] build = "*" skip = "" @@ -52,6 +55,13 @@ musllinux-s390x-image = "musllinux_1_2" musllinux-armv7l-image = "musllinux_1_2" musllinux-riscv64-image = "musllinux_1_2" +[tool.cibuildwheel.xbuild-files] +numpy = [ + "numpy/_core/include/numpy/_numpyconfig.h", + "numpy/_core/include/numpy/numpyconfig.h", + "numpy/_core/lib/libnpymath.a", + "numpy/random/lib/libnpyrandom.a", +] [tool.cibuildwheel.linux] repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel}" @@ -63,6 +73,7 @@ repair-wheel-command = "delocate-wheel --require-archs {delocate_archs} -w {dest repair-wheel-command = "delvewheel repair -w {dest_dir} -v {wheel}" [tool.cibuildwheel.android] +repair-wheel-command = "auditwheel repair --ldpaths {ldpaths} -w {dest_dir} {wheel}" [tool.cibuildwheel.ios] diff --git a/cibuildwheel/util/helpers.py b/cibuildwheel/util/helpers.py index 6eb79a95..a8a4df78 100644 --- a/cibuildwheel/util/helpers.py +++ b/cibuildwheel/util/helpers.py @@ -109,7 +109,7 @@ def parse_key_value_string( if kw_arg_names is None: kw_arg_names = [] - all_field_names = [*positional_arg_names, *kw_arg_names] + all_field_names = None if ("*" in kw_arg_names) else [*positional_arg_names, *kw_arg_names] shlexer = shlex.shlex(key_value_string, posix=True, punctuation_chars=";") shlexer.commenters = "" @@ -126,7 +126,7 @@ def parse_key_value_string( # check to see if the option name is specified field_name, sep, first_value = field[0].partition(":") if sep: - if field_name not in all_field_names: + if (all_field_names is not None) and (field_name not in all_field_names): msg = f"Failed to parse {key_value_string!r}. Unknown field name {field_name!r}" raise ValueError(msg) diff --git a/docs/configuration.md b/docs/configuration.md index 62bef786..ae05b420 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -58,8 +58,8 @@ cibuildwheel to run tests, add the following YAML to your CI config file: You can configure cibuildwheel with a config file, such as `pyproject.toml`. Options have the same names as the environment variable overrides, but are placed in `[tool.cibuildwheel]` and are lower case, with dashes, following -common [TOML](https://toml.io) practice. Anything placed in subsections `linux`, `windows`, -`macos`, or `pyodide` will only affect those platforms. Lists can be used +common [TOML](https://toml.io) practice. Anything placed in subsections +named after a platform will only affect those platforms. Lists can be used instead of strings for items that are naturally a list. Multiline strings also work just like in the environment variables. Environment variables will take precedence if defined. diff --git a/docs/data/how-it-works.png b/docs/data/how-it-works.png index e066fcdd758e027cdbcc7e62c0cd02460fa18371..3011593b55d1c52377eff70b3504b6dadb9c7d99 100644 GIT binary patch literal 98793 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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 literal 98369 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

(PLML(_0m=ZnjMaF+#2Wax0q27PXkI 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 B1BU Platform-specific files in the build environment + +When cross-compiling a package for Android, any dependencies in its [`build-system.requires`](https://packaging.python.org/en/latest/guides/writing-pyproject-toml/) are installed for the build platform. However, some dependencies contain platform-specific files such as headers and static libraries, which must correspond to the target platform. + +This option maps a [normalized](https://packaging.python.org/en/latest/specifications/name-normalization/#name-normalization) package name to a list of paths within that package. If the package is present in the build environment, then a matching version will be downloaded for the target platform, and used to overwrite the given paths within the build environment. + +The default value of this option includes [paths from popular packages](configuration.md#configuration-file). + +Platform-specific environment variables are also available:
+ `CIBW_XBUILD_FILES_ANDROID` + +#### Examples + +!!! tab examples "pyproject.toml" + + ```toml + [tool.cibuildwheel.xbuild-files] + package1 = ["some/header.h", "some/library.a"] + package2 = ["other/header.h"] + ``` + +!!! tab examples "Environment variables" + + ```yaml + CIBW_XBUILD_FILES: "package1: some/header.h some/library.a; package2: other/header.h" + ``` + + ### `repair-wheel-command` {: #repair-wheel-command env-var toml} > Execute a shell command to repair each built wheel @@ -923,8 +952,7 @@ Default: - on Linux: `'auditwheel repair -w {dest_dir} {wheel}'` - on macOS: `'delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}'` -- on Android: There is no default command, but cibuildwheel will add `libc++` to the - wheel if anything links against it. Setting a command will replace this behavior. +- on Android: `'auditwheel repair --ldpaths {ldpaths} -w {dest_dir} {wheel}'` - on Pyodide: You can use `pyodide auditwheel repair --libdir /path/to/libraries --output-dir {dest_dir} {wheel}` command to repair the wheel. Unlike other platforms, this command is not set by default as you need to explicitly specify the library directory. You might not want to use the libraries in the system @@ -939,6 +967,7 @@ The following placeholders must be used inside the command and will be replaced - `{wheel}` for the absolute path to the built wheel - `{dest_dir}` for the absolute path of the directory where to create the repaired wheel - `{delocate_archs}` (macOS only) comma-separated list of architectures in the wheel. +- `{ldpaths}` (Android only) colon-separated list of directories to search for external libraries, set by cibuildwheel to include any necessary locations in the NDK. You can add more directories by appending them with a colon separator after the placeholder, or by setting the `AUDITWHEEL_LD_LIBRARY_PATH` environment variable. You can use the `{package}` or `{project}` placeholders in your `repair-wheel-command` to refer to the package being built or the project root, respectively. diff --git a/docs/platforms.md b/docs/platforms.md index 33d82e21..89e17908 100644 --- a/docs/platforms.md +++ b/docs/platforms.md @@ -219,13 +219,9 @@ It also requires the following commands to be on the `PATH`: Android builds will honor the `ANDROID_API_LEVEL` environment variable to set the minimum supported [API level](https://developer.android.com/tools/releases/platforms) -for generated wheels. This will default to the minimum API level of the selected Python -version. - -If the [`repair-wheel-command`](options.md#repair-wheel-command) adds any libraries to -the wheel, then `ANDROID_API_LEVEL` must be at least 24. This is already the default -when building for Python 3.14 and later, but you may need to set it when building for -Python 3.13. +for generated wheels. This defaults to 24, which is supported by [99% of active +devices](https://dl.google.com/android/studio/metadata/distributions.json), and is the first +version to support RUNPATH, which auditwheel needs in order to graft external libraries. ### Build frontend support diff --git a/pyproject.toml b/pyproject.toml index be2b1ca5..99aac2e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,11 +45,7 @@ dependencies = [ "filelock", "humanize", "packaging>=20.9", - # patchelf is used for Android - "patchelf; (sys_platform == 'linux' or sys_platform == 'darwin') and (platform_machine == 'x86_64' or platform_machine == 'arm64' or platform_machine == 'aarch64')", "platformdirs", - "pyelftools>=0.29", - "wheel>=0.33.6", ] [project.optional-dependencies] diff --git a/test/test_android.py b/test/test_android.py index 2d52cb76..4037b004 100644 --- a/test/test_android.py +++ b/test/test_android.py @@ -13,7 +13,7 @@ from zipfile import ZipFile import pytest -from .test_projects import new_c_project +from .test_projects import new_c_project, new_meson_project from .utils import cibuildwheel_run, expected_wheels pytestmark = pytest.mark.android @@ -125,7 +125,7 @@ def test_frontend_good(tmp_path: Path, build_frontend_env: dict[str, str]) -> No tmp_path, add_env={**cp313_env, **build_frontend_env, "CIBW_TEST_COMMAND": "python -m site"}, ) - assert wheels == [f"spam-0.1.0-cp313-cp313-android_21_{native_arch.android_abi}.whl"] + assert wheels == [f"spam-0.1.0-cp313-cp313-android_24_{native_arch.android_abi}.whl"] @pytest.mark.parametrize("frontend", ["pip"]) @@ -136,7 +136,10 @@ def test_frontend_bad(frontend: str, tmp_path: Path, capfd: pytest.CaptureFixtur tmp_path, add_env={**cp313_env, "CIBW_BUILD_FRONTEND": frontend}, ) - assert "Android requires the build frontend to be 'build'" in capfd.readouterr().err + assert ( + f"Android requires the build frontend to be 'build' or 'uv', not '{frontend}'" + in capfd.readouterr().err + ) @needs_emulator @@ -162,7 +165,7 @@ def test_archs(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None: ), }, ) - assert wheels == [f"spam-0.1.0-cp313-cp313-android_21_{arch.android_abi}.whl" for arch in archs] + assert wheels == [f"spam-0.1.0-cp313-cp313-android_24_{arch.android_abi}.whl" for arch in archs] stdout, stderr = capfd.readouterr() lines = (line for line in stdout.splitlines() if line.startswith("Hello from")) @@ -435,13 +438,25 @@ def test_verbosity(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None: @needs_emulator def test_api_level(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None: - project = new_c_project() + project = new_c_project( + # Check that the the compiler options are set correctly. + spam_c_top_level_add=dedent( + """\ + #if __ANDROID_API__ != 33 + #error Unexpected API level; the following syntax error will show the actual value: + __ANDROID_API__ + #endif + """ + ) + ) project.files["pyproject.toml"] = dedent( """\ [build-system] requires = ["setuptools"] [tool.cibuildwheel] + # Test setting API level in pyproject.toml (test_libcxx covers setting + # it in the outer environment.) android.environment.ANDROID_API_LEVEL = "33" android.environment.PIP_EXTRA_INDEX_URL = "https://chaquo.com/pypi-13.1" """ @@ -486,17 +501,21 @@ def test_libcxx(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None: "PATH": non_venv_path, } - # Including external libraries requires API level 24. + # Including external libraries requires API level 24. This is enforced by auditwheel. + cp313_android_21_env = { + **cp313_test_env, + # Test setting API level in the outer environment (test_api_level covers setting + # it in pyproject.toml.) + "ANDROID_API_LEVEL": "21", + } with pytest.raises(CalledProcessError): - cibuildwheel_run(project_dir, add_env=cp313_test_env, output_dir=output_dir) - assert "libc++_shared.so requires ANDROID_API_LEVEL to be at least 24" in capfd.readouterr().err - - wheels = cibuildwheel_run( - project_dir, - add_env={**cp313_test_env, "ANDROID_API_LEVEL": "24"}, - output_dir=output_dir, + cibuildwheel_run(project_dir, add_env=cp313_android_21_env, output_dir=output_dir) + assert ( + "Grafting libraries with RUNPATH requires API level 24 or higher" in capfd.readouterr().err ) - assert len(wheels) == 1 + + wheels = cibuildwheel_run(project_dir, add_env=cp313_test_env, output_dir=output_dir) + assert wheels == [f"spam-0.1.0-cp313-cp313-android_24_{native_arch.android_abi}.whl"] names = ZipFile(output_dir / wheels[0]).namelist() libcxx_names = [ name for name in names if re.fullmatch(r"spam\.libs/libc\+\+_shared-[0-9a-f]{8}\.so", name) @@ -504,16 +523,177 @@ def test_libcxx(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None: assert len(libcxx_names) == 1 assert "ham: 1, spam: 0" in capfd.readouterr().out - # A C package should not include libc++. + # A C package should not include libc++, and can therefore use an older API level. rmtree(project_dir) rmtree(output_dir) new_c_project().generate(project_dir) - wheels = cibuildwheel_run(project_dir, add_env=cp313_env, output_dir=output_dir) - assert len(wheels) == 1 + wheels = cibuildwheel_run(project_dir, add_env=cp313_android_21_env, output_dir=output_dir) + assert wheels == [f"spam-0.1.0-cp313-cp313-android_21_{native_arch.android_abi}.whl"] for name in ZipFile(output_dir / wheels[0]).namelist(): assert ".libs" not in name +@needs_emulator +def test_repair_none(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None: + new_c_project(setup_py_extension_args_add="language='c++'").generate(tmp_path) + with pytest.raises(CalledProcessError): + cibuildwheel_run( + tmp_path, + add_env={ + **cp313_env, + "CIBW_REPAIR_WHEEL_COMMAND": "", + "CIBW_TEST_COMMAND": "python -c 'import spam'", + }, + ) + assert 'dlopen failed: library "libc++_shared.so" not found' in capfd.readouterr().err + + +def test_repair_ldpaths(tmp_path: Path) -> None: + new_c_project().generate(tmp_path) + repair_path = tmp_path / "repair.py" + repair_path.write_text( + dedent( + """\ + #!/usr/bin/env python + import shutil + import sys + from pathlib import Path + + assert len(sys.argv) == 4, sys.argv + ldpaths = list(map(Path, sys.argv[1].split(":"))) + dest_dir = sys.argv[2] + wheel = sys.argv[3] + + for name in ["libc++_shared.so", "libomp.so"]: + assert any((lp / name).exists() for lp in ldpaths), (name, ldpaths) + + shutil.copy(wheel, dest_dir) + """ + ) + ) + repair_path.chmod(0o755) + + wheels = cibuildwheel_run( + tmp_path, + add_env={ + **cp313_env, + "CIBW_REPAIR_WHEEL_COMMAND": f"{repair_path} {{ldpaths}} {{dest_dir}} {{wheel}}", + }, + ) + assert wheels == [f"spam-0.1.0-cp313-cp313-android_24_{native_arch.android_abi}.whl"] + + +@pytest.mark.parametrize( + ("script", "error"), + [ + ("", "did not produce a wheel"), + ("touch $dest_dir/one.whl $dest_dir/two.whl", "produced multiple wheels"), + ("touch $dest_dir/one-0.0.1-py3-none-any.whl", "pure Python wheel was generated"), + ], +) +def test_repair_error( + script: str, error: str, tmp_path: Path, capfd: pytest.CaptureFixture[str] +) -> None: + new_c_project().generate(tmp_path) + repair_path = tmp_path / "repair.sh" + repair_path.write_text( + dedent( + f"""\ + #!/bin/sh + dest_dir=$1 + {script} + """ + ) + ) + repair_path.chmod(0o755) + + with pytest.raises(CalledProcessError): + cibuildwheel_run( + tmp_path, + add_env={**cp313_env, "CIBW_REPAIR_WHEEL_COMMAND": f"{repair_path} {{dest_dir}}"}, + ) + assert error in capfd.readouterr().err + + +# This also tests integration with pkgconf, because Meson uses it to find Python. +@needs_emulator +def test_meson(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None: + # Alter spam.filter to return the value of a Fortran function. + new_meson_project( + spam_c_top_level_add="int fortran_func_();", + spam_c_function_add="sts = fortran_func_();", + project_args_add="'fortran',", + extension_args_add="'fortran.f90', link_language: 'fortran',", + ).generate(tmp_path) + + # TODO: remove once meson-python has a release with Android support. + pyproject_path = tmp_path / "pyproject.toml" + pyproject_path.write_text( + pyproject_path.read_text().replace( + "meson-python", "meson-python @ git+https://github.com/mesonbuild/meson-python@main" + ) + ) + + # Add Fortran code. + (tmp_path / "fortran.f90").write_text( + dedent( + """\ + integer*4 function fortran_func() + fortran_func = 42 + end + """ + ) + ) + + script = 'import spam; print(f"result: {spam.filter("")}")' + cibuildwheel_run( + tmp_path, + add_env={**cp313_env, "CIBW_TEST_COMMAND": f"python -c '{script}'"}, + ) + assert "result: 42" in capfd.readouterr().out + + +@needs_emulator +def test_xbuild_files(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None: + # Verify that we've replaced the correct files by compiling against a non-trivial + # function from libnpymath.a. + new_c_project( + setup_py_add=dedent( + """\ + import numpy as np + np_include = np.get_include() + np_lib = f"{np_include}/../lib" + libraries.append("npymath") + """ + ), + setup_py_extension_args_add="include_dirs=[np_include], library_dirs=[np_lib]", + spam_c_top_level_add="#include ", + spam_c_function_add="sts = npy_float_to_half(42);", + ).generate(tmp_path) + + (tmp_path / "pyproject.toml").write_text( + dedent( + """\ + [build-system] + requires = ["setuptools", "numpy==2.3.2"] + """ + ) + ) + + script = 'import spam; print(f"result: {spam.filter(""):#x}")' + cibuildwheel_run( + tmp_path, + add_env={ + **cp313_env, + # TODO: remove this once there are official Android NumPy wheels on PyPI. + "PIP_EXTRA_INDEX_URL": "https://chaquo.com/pypi-test", + "CIBW_ARCHS": "all", # Include both native and non-native archs. + "CIBW_TEST_COMMAND": f"python -c '{script}'", + }, + ) + assert "result: 0x5140" in capfd.readouterr().out + + @needs_emulator def test_setuptools_rust(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None: """ diff --git a/test/test_projects/meson.py b/test/test_projects/meson.py index c3b14e17..2c5b2720 100644 --- a/test/test_projects/meson.py +++ b/test/test_projects/meson.py @@ -22,6 +22,7 @@ archs = ["auto64"] MESON_BUILD_TEMPLATE = r""" project('spam', 'c', + {{ project_args_add | indent(2) }} version: '0.1.0', default_options: ['warning_level=2'], ) @@ -30,6 +31,7 @@ py = import('python').find_installation(pure: false) py.extension_module('spam', 'spam.c', + {{ extension_args_add | indent(2) }} install: true, ) """ @@ -39,6 +41,8 @@ def new_meson_project( *, spam_c_top_level_add: str = "", spam_c_function_add: str = "", + project_args_add: str = "", + extension_args_add: str = "", ) -> TestProject: project = TestProject() @@ -54,6 +58,8 @@ def new_meson_project( { "spam_c_top_level_add": spam_c_top_level_add, "spam_c_function_add": spam_c_function_add, + "project_args_add": project_args_add, + "extension_args_add": extension_args_add, } ) diff --git a/test/test_projects/setuptools.py b/test/test_projects/setuptools.py index 20f8bfb5..2f48039e 100644 --- a/test/test_projects/setuptools.py +++ b/test/test_projects/setuptools.py @@ -82,9 +82,10 @@ import sys from setuptools import setup, Extension +libraries = [] + {{ setup_py_add }} -libraries = [] # Emscripten fails if you pass -lc... # See: https://github.com/emscripten-core/emscripten/issues/16680 if sys.platform.startswith('linux') and "emscripten" not in os.environ.get("_PYTHON_HOST_PLATFORM", ""): diff --git a/test/utils.py b/test/utils.py index e274ed0d..f023c0c1 100644 --- a/test/utils.py +++ b/test/utils.py @@ -177,6 +177,7 @@ def expected_wheels( musllinux_versions: list[str] | None = None, macosx_deployment_target: str | None = None, iphoneos_deployment_target: str | None = None, + android_api_level: int | None = None, machine_arch: str | None = None, platform: str | None = None, python_abi_tags: list[str] | None = None, @@ -201,6 +202,9 @@ def expected_wheels( if iphoneos_deployment_target is None: iphoneos_deployment_target = os.environ.get("IPHONEOS_DEPLOYMENT_TARGET", "13.0") + if android_api_level is None: + android_api_level = int(os.environ.get("ANDROID_API_LEVEL", "24")) + architectures = [machine_arch] if not single_arch: if platform == "linux" and full_auto: @@ -226,6 +230,7 @@ def expected_wheels( musllinux_versions=musllinux_versions, macosx_deployment_target=macosx_deployment_target, iphoneos_deployment_target=iphoneos_deployment_target, + android_api_level=android_api_level, platform=platform, python_abi_tags=python_abi_tags, include_universal2=include_universal2, @@ -242,6 +247,7 @@ def _expected_wheels( musllinux_versions: list[str] | None, macosx_deployment_target: str, iphoneos_deployment_target: str, + android_api_level: int, platform: str, python_abi_tags: list[str] | None, include_universal2: bool, @@ -387,12 +393,7 @@ def _expected_wheels( platform_tags.append(f"macosx_{min_macosx.replace('.', '_')}_universal2") elif platform == "android": - api_level = { - "cp313-cp313": 21, - "cp314-cp314": 24, - "cp315-cp315": 24, - }[python_abi_tag] - platform_tags = [f"android_{api_level}_{machine_arch}"] + platform_tags = [f"android_{android_api_level}_{machine_arch}"] elif platform == "ios": if machine_arch == "x86_64": diff --git a/unit_test/options_test.py b/unit_test/options_test.py index 8c86026d..77fb29ae 100644 --- a/unit_test/options_test.py +++ b/unit_test/options_test.py @@ -667,3 +667,51 @@ def test_xbuild_tools_handling(tmp_path: Path, definition: str, expected: list[s local = options.build_options("cp313-ios_13_0_arm64_iphoneos") assert local.xbuild_tools == expected + + +DEFAULT_XBUILD_FILES = { + "numpy": [ + "numpy/_core/include/numpy/_numpyconfig.h", + "numpy/_core/include/numpy/numpyconfig.h", + "numpy/_core/lib/libnpymath.a", + "numpy/random/lib/libnpyrandom.a", + ] +} + + +@pytest.mark.parametrize( + ("definition", "expected"), + [ + ("", DEFAULT_XBUILD_FILES), + ('xbuild-files = ""', {}), + ('xbuild-files = "package1: file1"', {"package1": ["file1"]}), + ( + "xbuild-files = \"package1: 'file1 with space'; package2: file2a file2b\"", + {"package1": ["file1 with space"], "package2": ["file2a", "file2b"]}, + ), + ], +) +def test_xbuild_files(tmp_path: Path, definition: str, expected: dict[str, list[str]]) -> None: + args = CommandLineArguments.defaults() + args.package_dir = tmp_path + + pyproject_toml: Path = tmp_path / "pyproject.toml" + pyproject_toml.write_text( + textwrap.dedent( + f"""\ + [tool.cibuildwheel] + {definition} + """ + ) + ) + + options = Options(platform="ios", command_line_arguments=args, env={}) + assert options.build_options(None).xbuild_files == expected + + pyproject_toml.write_text( + "[tool.cibuildwheel.xbuild-files]\n" + + "\n".join(f"{package} = {files}" for package, files in expected.items()) + ) + + options = Options(platform="ios", command_line_arguments=args, env={}) + assert options.build_options(None).xbuild_files == expected diff --git a/unit_test/utils_test.py b/unit_test/utils_test.py index 7a58ad49..85f38ebf 100644 --- a/unit_test/utils_test.py +++ b/unit_test/utils_test.py @@ -212,6 +212,28 @@ def test_parse_key_value_string() -> None: } +def test_parse_key_value_string_unknown_name() -> None: + # Unknown fields are not allowed by default. + with pytest.raises(ValueError, match=r"Failed to parse 'key: value'. Unknown field name 'key'"): + parse_key_value_string("key: value") + + # Unknown fields can be enabled by passing "*". + assert parse_key_value_string( + "key: value", + kw_arg_names=["*"], + ) == { + "key": ["value"], + } + + assert parse_key_value_string( + "key1: value1a value1b; key2: value2", + kw_arg_names=["*"], + ) == { + "key1": ["value1a", "value1b"], + "key2": ["value2"], + } + + def test_flexible_version_comparisons() -> None: assert FlexibleVersion("2.0") == FlexibleVersion("2") assert FlexibleVersion("2.0") < FlexibleVersion("2.1")