Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion cibuildwheel/platforms/android.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import shutil
import subprocess
import sysconfig
from collections.abc import Iterable, Iterator
from collections.abc import Iterable, Iterator, MutableMapping
from dataclasses import dataclass
from os.path import relpath
from pathlib import Path
Expand Down Expand Up @@ -390,6 +390,11 @@ def setup_android_env(
for key in ["CFLAGS", "CXXFLAGS"]:
android_env[key] += " " + opt

# Cargo target linker need to be specified after CC is set
setup_rust_cross_compile(config, android_env)

setup_PYO3_cross_compile(python_dir, android_env)

# 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:
Expand All @@ -398,6 +403,47 @@ def setup_android_env(
return android_env


def setup_rust_cross_compile(
python_configuration: PythonConfiguration,
env: MutableMapping[str, str],
) -> None:
cargo_target = android_triplet(python_configuration.identifier)
call("rustup", "target", "add", cargo_target)

# CARGO_BUILD_TARGET is the variable used by Cargo and setuptools_rust
if env.get("CARGO_BUILD_TARGET"):
if env["CARGO_BUILD_TARGET"] != cargo_target:
log.notice("Not overriding CARGO_BUILD_TARGET as it has already been set")
# No message if it was set to what we were planning to set it to
elif cargo_target:
cargo_target_linker_env_name = (
f"CARGO_TARGET_{cargo_target.upper().replace('-', '_')}_LINKER"
)
log.notice(
f"Setting CARGO_BUILD_TARGET={cargo_target} and {cargo_target_linker_env_name} for cross-compilation"
)
env["CARGO_BUILD_TARGET"] = cargo_target
# CC has already been set by calling android.py (it calls android-env.sh)
env[f"{cargo_target_linker_env_name}"] = env["CC"]
else:
log.warning(f"Unable to configure Rust cross-compilation for architecture {cargo_target}")


def setup_PYO3_cross_compile(
python_dir: Path,
env: MutableMapping[str, str],
) -> None:
# All Python extension modules must therefore be explicitly linked against libpython3.x.so when building for Android.
# See: https://peps.python.org/pep-0738/#linkage
# For projects using PyO3, this requires setting PYO3_CROSS_LIB_DIR to the directory containing libpython3.x.so.
# See: https://pyo3.rs/v0.27.1/building-and-distribution.html#cross-compiling
if env.get("PYO3_CROSS_LIB_DIR"):
log.notice("Not overriding PYO3_CROSS_LIB_DIR as it has already been set")
else:
env["PYO3_CROSS_LIB_DIR"] = str(python_dir / "prefix" / "lib")
log.notice("Setting PYO3_CROSS_LIB_DIR for PyO3 cross-compilation")


def before_build(state: BuildState) -> None:
if state.options.before_build:
log.step("Running before_build...")
Expand Down