Bug Description
When cross-compiling an abi3 extension module for Android with PYO3_CROSS_LIB_DIR pointing to a Python 3.14 installation (via build-details.json), the linker fails with:
ld.lld: error: unable to find library -lpython3.7m
The target has Python 3.14, but pyo3 generates -lpython3.7m instead.
See the full CI log: https://github.com/PyO3/maturin-action/actions/runs/24198305015/job/70634639917
Root Cause
In from_pyo3_config_file_env(), after reading the config file (which has version=3.14, abi3=false), the following happens:
config.abi3 |= is_abi3() → sets abi3 = true (from Cargo feature)
config.fixup_for_abi3_version(get_abi3_version()) → unconditionally sets self.version = 3.7 (from abi3-py37 minimum)
apply_default_lib_name_to_config_file() → computes lib_name from the now-downgraded version 3.7
default_lib_name_unix() for version 3.7 returns "python3.7m" (the m abiflag workaround for <= 3.7)
- Since
is_linking_libpython_for_target() returns true for Android, this incorrect library name is emitted as -lpython3.7m
The fundamental problem is that fixup_for_abi3_version downgrades version to the abi3 minimum, but version is then also used to derive the link library name. The abi3 minimum version is relevant for the Python C API compatibility level, but the link library should match the actual target Python installation, not the abi3 minimum.
Steps to Reproduce
- Set up cross-compilation for
aarch64-linux-android
- Download the Android Python 3.14 standalone build
- Set
PYO3_CROSS_LIB_DIR to the Python prefix/lib directory (containing build-details.json)
- Build an abi3 pyo3 crate (e.g., with
abi3-py37 feature)
The build will fail with unable to find library -lpython3.7m.
Environment
- pyo3 v0.28.2
- Target:
aarch64-linux-android
- Python: 3.14.3 (standalone Android build from python.org)
- maturin sets
PYO3_CONFIG_FILE with version=3.14, abi3=false, lib_dir=<PYO3_CROSS_LIB_DIR>
Bug Description
When cross-compiling an abi3 extension module for Android with
PYO3_CROSS_LIB_DIRpointing to a Python 3.14 installation (viabuild-details.json), the linker fails with:The target has Python 3.14, but pyo3 generates
-lpython3.7minstead.See the full CI log: https://github.com/PyO3/maturin-action/actions/runs/24198305015/job/70634639917
Root Cause
In
from_pyo3_config_file_env(), after reading the config file (which hasversion=3.14,abi3=false), the following happens:config.abi3 |= is_abi3()→ setsabi3 = true(from Cargo feature)config.fixup_for_abi3_version(get_abi3_version())→ unconditionally setsself.version = 3.7(fromabi3-py37minimum)apply_default_lib_name_to_config_file()→ computeslib_namefrom the now-downgraded version 3.7default_lib_name_unix()for version 3.7 returns"python3.7m"(themabiflag workaround for <= 3.7)is_linking_libpython_for_target()returnstruefor Android, this incorrect library name is emitted as-lpython3.7mThe fundamental problem is that
fixup_for_abi3_versiondowngradesversionto the abi3 minimum, butversionis then also used to derive the link library name. The abi3 minimum version is relevant for the Python C API compatibility level, but the link library should match the actual target Python installation, not the abi3 minimum.Steps to Reproduce
aarch64-linux-androidPYO3_CROSS_LIB_DIRto the Python prefix/lib directory (containingbuild-details.json)abi3-py37feature)The build will fail with
unable to find library -lpython3.7m.Environment
aarch64-linux-androidPYO3_CONFIG_FILEwithversion=3.14,abi3=false,lib_dir=<PYO3_CROSS_LIB_DIR>