Skip to content

feat: add automatic Android API Level detection via getprop - #3153

Open
MartheusX wants to merge 1 commit into
PyO3:mainfrom
MartheusX:fix-android-api-detection
Open

feat: add automatic Android API Level detection via getprop#3153
MartheusX wants to merge 1 commit into
PyO3:mainfrom
MartheusX:fix-android-api-detection

Conversation

@MartheusX

Copy link
Copy Markdown

Description

Currently, maturin requires the ANDROID_API_LEVEL environment variable to be explicitly set when building on-device in environments like Termux. If missing, the build fails even though the host system is a live Android instance where this information is readily available.

This PR introduces a fallback mechanism:

  1. It checks if the current platform is Android.
  2. If ANDROID_API_LEVEL and other clues (linker/CC) are missing, it attempts to query getprop ro.build.version.sdk.
  3. This significantly improves the developer experience for users building Rust-based Python packages directly on Android devices.

Motivation

I encountered this issue while trying to install tools in Termux on my Redmi Note 8 Pro. Automating this step removes a manual barrier for many mobile developers.

Testing

  • Verified on Android 11 (API 30) within Termux.
  • Confirmed that manual environment variables still take priority over this fallback.

@messense

Copy link
Copy Markdown
Member

I don't believe this is strictly required, ANDROID_API_LEVEL is not required since 1.13.0 release as long as you have clang installed which is the case when you try to develop on Termux I think.

Though it does not hurt to include this, but please verify the claim.

@MartheusX

Copy link
Copy Markdown
Author

​"I have verified the claim on my another device (Xiaomi Poco F3, Android 13, API 33).
​As shown in the attached screenshot, clang -
Screenshot_2026-04-24-06-39-43-252_com termux
dumpmachine returns aarch64-unknown-linux-android24, but the actual system API level retrieved via getprop is 33.
​Relying solely on clang clues is inaccurate for on-device builds in Termux, as clang defaults to a much lower API level (24) than the host system actually supports. My proposed getprop fallback ensures that maturin correctly identifies the host's actual capabilities (API 33) when building natively.
​Without this fallback or a manual ANDROID_API_LEVEL export, the developer is forced to manually investigate and set the correct version, which goes against the goal of making maturin 'just work'."

@messense

Copy link
Copy Markdown
Member

So you are saying the lower API level 24 does not work on Termux, any errors? Could you also check the output of python3 -m pip debug --verbose on Termux, it should show the supported platform tags. Thanks!

@Benjamin-Loison

Benjamin-Loison commented Aug 3, 2026

Copy link
Copy Markdown

@messense:

On Fairphone 4 LineageOS 23.2:

On 08/06/2026 with Python 3.13:

getprop ro.build.version.sdk
36
pip install -U pydantic-core
Output:
Requirement already satisfied: pydantic-core in /data/data/com.termux/files/usr/lib/python3.13/site-packages (2.41.5)
Collecting pydantic-core
  Using cached pydantic_core-2.47.0.tar.gz (476 kB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... error
  error: subprocess-exited-with-error
  
  × Preparing metadata (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [9 lines of output]
      🍹 Building a mixed python/rust project
      🐍 Found CPython 3.13 at /data/data/com.termux/files/usr/bin/python3.13
      🔗 Found pyo3 bindings
      📡 Using build options bindings from pyproject.toml
      💥 maturin failed
        Caused by: Failed to determine Android API level. Please set the ANDROID_API_LEVEL environment variable.
      Error running maturin: Command '['maturin', 'pep517', 'write-dist-info', '--metadata-directory', '/data/data/com.termux/files/usr/tmp/pip-modern-metadata-feamsb8_', '--interpreter', '/data/data/com.termux/files/usr/bin/python3.13']' returned non-zero exit status 1.
      Checking for Rust toolchain....
      Running `maturin pep517 write-dist-info --metadata-directory /data/data/com.termux/files/usr/tmp/pip-modern-metadata-feamsb8_ --interpreter /data/data/com.termux/files/usr/bin/python3.13`
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed

× Encountered error while generating package metadata.
╰─> pydantic-core

note: This is an issue with the package mentioned above, not pip.
hint: See above for details.

Source: Benjamin_Loison/pydantic-core/issues/2

export ANDROID_API_LEVEL=$(getprop ro.build.version.sdk)

seems to have solved the issue according to my notes.

python3 -m pip debug --verbose
Output:
WARNING: This command is only meant for debugging. Do not use this with automation for parsing and getting these details, since the output and options of this command may change without notice.
pip version: pip 26.2 from /data/data/com.termux/files/usr/lib/python3.14/site-packages/pip (python 3.14)
sys.version: 3.14.6 (main, Jul  5 2026, 10:35:55) [Clang 21.0.0 (https://android.googlesource.com/toolchain/llvm-project 5e96669f0
sys.executable: /data/data/com.termux/files/usr/bin/python3
sys.getdefaultencoding: utf-8
sys.getfilesystemencoding: utf-8
locale.getencoding: utf-8
sys.platform: android
sys.implementation:
  name: cpython
'cert' config value: global
REQUESTS_CA_BUNDLE: None
CURL_CA_BUNDLE: None
pip._vendor.certifi.where(): /data/data/com.termux/files/usr/lib/python3.14/site-packages/pip/_vendor/certifi/cacert.pem
pip._vendor.DEBUNDLED: False
vendored library versions:
  CacheControl==0.14.4 (Unable to locate actual module version, using vendor.txt specified version)
  distlib==0.4.2
  distro==1.9.0
  msgpack==1.1.2
  packaging==26.2
  platformdirs==4.10.0
  pyproject-hooks==1.2.0
  requests==2.34.2
  certifi==2026.06.17
  idna==3.18
  urllib3==2.7.0
  rich==14.2.0 (Unable to locate actual module version, using vendor.txt specified version)
  pygments==2.20.0
  resolvelib==1.2.1
  setuptools==70.3.0 (Unable to locate actual module version, using vendor.txt specified version)
  tomli==2.4.1
  tomli-w==1.2.0
  truststore==0.10.4
Compatible tags: 327
  cp314-cp314-android_arm64_v8a
  cp314-cp314-android_24_arm64_v8a
  cp314-cp314-android_23_arm64_v8a
  cp314-cp314-android_22_arm64_v8a
  cp314-cp314-android_21_arm64_v8a
  cp314-cp314-android_20_arm64_v8a
  cp314-cp314-android_19_arm64_v8a
  cp314-cp314-android_18_arm64_v8a
  cp314-cp314-android_17_arm64_v8a
  cp314-cp314-android_16_arm64_v8a
  cp314-abi3-android_arm64_v8a
  cp314-abi3-android_24_arm64_v8a
  cp314-abi3-android_23_arm64_v8a
  cp314-abi3-android_22_arm64_v8a
  cp314-abi3-android_21_arm64_v8a
  cp314-abi3-android_20_arm64_v8a
  cp314-abi3-android_19_arm64_v8a
  cp314-abi3-android_18_arm64_v8a
  cp314-abi3-android_17_arm64_v8a
  cp314-abi3-android_16_arm64_v8a
  cp314-none-android_arm64_v8a
  cp314-none-android_24_arm64_v8a
  cp314-none-android_23_arm64_v8a
  cp314-none-android_22_arm64_v8a
  cp314-none-android_21_arm64_v8a
  cp314-none-android_20_arm64_v8a
  cp314-none-android_19_arm64_v8a
  cp314-none-android_18_arm64_v8a
  cp314-none-android_17_arm64_v8a
  cp314-none-android_16_arm64_v8a
  cp313-abi3-android_arm64_v8a
  cp313-abi3-android_24_arm64_v8a
  cp313-abi3-android_23_arm64_v8a
  cp313-abi3-android_22_arm64_v8a
  cp313-abi3-android_21_arm64_v8a
  cp313-abi3-android_20_arm64_v8a
  cp313-abi3-android_19_arm64_v8a
  cp313-abi3-android_18_arm64_v8a
  cp313-abi3-android_17_arm64_v8a
  cp313-abi3-android_16_arm64_v8a
  cp312-abi3-android_arm64_v8a
  cp312-abi3-android_24_arm64_v8a
  cp312-abi3-android_23_arm64_v8a
  cp312-abi3-android_22_arm64_v8a
  cp312-abi3-android_21_arm64_v8a
  cp312-abi3-android_20_arm64_v8a
  cp312-abi3-android_19_arm64_v8a
  cp312-abi3-android_18_arm64_v8a
  cp312-abi3-android_17_arm64_v8a
  cp312-abi3-android_16_arm64_v8a
  cp311-abi3-android_arm64_v8a
  cp311-abi3-android_24_arm64_v8a
  cp311-abi3-android_23_arm64_v8a
  cp311-abi3-android_22_arm64_v8a
  cp311-abi3-android_21_arm64_v8a
  cp311-abi3-android_20_arm64_v8a
  cp311-abi3-android_19_arm64_v8a
  cp311-abi3-android_18_arm64_v8a
  cp311-abi3-android_17_arm64_v8a
  cp311-abi3-android_16_arm64_v8a
  cp310-abi3-android_arm64_v8a
  cp310-abi3-android_24_arm64_v8a
  cp310-abi3-android_23_arm64_v8a
  cp310-abi3-android_22_arm64_v8a
  cp310-abi3-android_21_arm64_v8a
  cp310-abi3-android_20_arm64_v8a
  cp310-abi3-android_19_arm64_v8a
  cp310-abi3-android_18_arm64_v8a
  cp310-abi3-android_17_arm64_v8a
  cp310-abi3-android_16_arm64_v8a
  cp39-abi3-android_arm64_v8a
  cp39-abi3-android_24_arm64_v8a
  cp39-abi3-android_23_arm64_v8a
  cp39-abi3-android_22_arm64_v8a
  cp39-abi3-android_21_arm64_v8a
  cp39-abi3-android_20_arm64_v8a
  cp39-abi3-android_19_arm64_v8a
  cp39-abi3-android_18_arm64_v8a
  cp39-abi3-android_17_arm64_v8a
  cp39-abi3-android_16_arm64_v8a
  cp38-abi3-android_arm64_v8a
  cp38-abi3-android_24_arm64_v8a
  cp38-abi3-android_23_arm64_v8a
  cp38-abi3-android_22_arm64_v8a
  cp38-abi3-android_21_arm64_v8a
  cp38-abi3-android_20_arm64_v8a
  cp38-abi3-android_19_arm64_v8a
  cp38-abi3-android_18_arm64_v8a
  cp38-abi3-android_17_arm64_v8a
  cp38-abi3-android_16_arm64_v8a
  cp37-abi3-android_arm64_v8a
  cp37-abi3-android_24_arm64_v8a
  cp37-abi3-android_23_arm64_v8a
  cp37-abi3-android_22_arm64_v8a
  cp37-abi3-android_21_arm64_v8a
  cp37-abi3-android_20_arm64_v8a
  cp37-abi3-android_19_arm64_v8a
  cp37-abi3-android_18_arm64_v8a
  cp37-abi3-android_17_arm64_v8a
  cp37-abi3-android_16_arm64_v8a
  cp36-abi3-android_arm64_v8a
  cp36-abi3-android_24_arm64_v8a
  cp36-abi3-android_23_arm64_v8a
  cp36-abi3-android_22_arm64_v8a
  cp36-abi3-android_21_arm64_v8a
  cp36-abi3-android_20_arm64_v8a
  cp36-abi3-android_19_arm64_v8a
  cp36-abi3-android_18_arm64_v8a
  cp36-abi3-android_17_arm64_v8a
  cp36-abi3-android_16_arm64_v8a
  cp35-abi3-android_arm64_v8a
  cp35-abi3-android_24_arm64_v8a
  cp35-abi3-android_23_arm64_v8a
  cp35-abi3-android_22_arm64_v8a
  cp35-abi3-android_21_arm64_v8a
  cp35-abi3-android_20_arm64_v8a
  cp35-abi3-android_19_arm64_v8a
  cp35-abi3-android_18_arm64_v8a
  cp35-abi3-android_17_arm64_v8a
  cp35-abi3-android_16_arm64_v8a
  cp34-abi3-android_arm64_v8a
  cp34-abi3-android_24_arm64_v8a
  cp34-abi3-android_23_arm64_v8a
  cp34-abi3-android_22_arm64_v8a
  cp34-abi3-android_21_arm64_v8a
  cp34-abi3-android_20_arm64_v8a
  cp34-abi3-android_19_arm64_v8a
  cp34-abi3-android_18_arm64_v8a
  cp34-abi3-android_17_arm64_v8a
  cp34-abi3-android_16_arm64_v8a
  cp33-abi3-android_arm64_v8a
  cp33-abi3-android_24_arm64_v8a
  cp33-abi3-android_23_arm64_v8a
  cp33-abi3-android_22_arm64_v8a
  cp33-abi3-android_21_arm64_v8a
  cp33-abi3-android_20_arm64_v8a
  cp33-abi3-android_19_arm64_v8a
  cp33-abi3-android_18_arm64_v8a
  cp33-abi3-android_17_arm64_v8a
  cp33-abi3-android_16_arm64_v8a
  cp32-abi3-android_arm64_v8a
  cp32-abi3-android_24_arm64_v8a
  cp32-abi3-android_23_arm64_v8a
  cp32-abi3-android_22_arm64_v8a
  cp32-abi3-android_21_arm64_v8a
  cp32-abi3-android_20_arm64_v8a
  cp32-abi3-android_19_arm64_v8a
  cp32-abi3-android_18_arm64_v8a
  cp32-abi3-android_17_arm64_v8a
  cp32-abi3-android_16_arm64_v8a
  py314-none-android_arm64_v8a
  py314-none-android_24_arm64_v8a
  py314-none-android_23_arm64_v8a
  py314-none-android_22_arm64_v8a
  py314-none-android_21_arm64_v8a
  py314-none-android_20_arm64_v8a
  py314-none-android_19_arm64_v8a
  py314-none-android_18_arm64_v8a
  py314-none-android_17_arm64_v8a
  py314-none-android_16_arm64_v8a
  py3-none-android_arm64_v8a
  py3-none-android_24_arm64_v8a
  py3-none-android_23_arm64_v8a
  py3-none-android_22_arm64_v8a
  py3-none-android_21_arm64_v8a
  py3-none-android_20_arm64_v8a
  py3-none-android_19_arm64_v8a
  py3-none-android_18_arm64_v8a
  py3-none-android_17_arm64_v8a
  py3-none-android_16_arm64_v8a
  py313-none-android_arm64_v8a
  py313-none-android_24_arm64_v8a
  py313-none-android_23_arm64_v8a
  py313-none-android_22_arm64_v8a
  py313-none-android_21_arm64_v8a
  py313-none-android_20_arm64_v8a
  py313-none-android_19_arm64_v8a
  py313-none-android_18_arm64_v8a
  py313-none-android_17_arm64_v8a
  py313-none-android_16_arm64_v8a
  py312-none-android_arm64_v8a
  py312-none-android_24_arm64_v8a
  py312-none-android_23_arm64_v8a
  py312-none-android_22_arm64_v8a
  py312-none-android_21_arm64_v8a
  py312-none-android_20_arm64_v8a
  py312-none-android_19_arm64_v8a
  py312-none-android_18_arm64_v8a
  py312-none-android_17_arm64_v8a
  py312-none-android_16_arm64_v8a
  py311-none-android_arm64_v8a
  py311-none-android_24_arm64_v8a
  py311-none-android_23_arm64_v8a
  py311-none-android_22_arm64_v8a
  py311-none-android_21_arm64_v8a
  py311-none-android_20_arm64_v8a
  py311-none-android_19_arm64_v8a
  py311-none-android_18_arm64_v8a
  py311-none-android_17_arm64_v8a
  py311-none-android_16_arm64_v8a
  py310-none-android_arm64_v8a
  py310-none-android_24_arm64_v8a
  py310-none-android_23_arm64_v8a
  py310-none-android_22_arm64_v8a
  py310-none-android_21_arm64_v8a
  py310-none-android_20_arm64_v8a
  py310-none-android_19_arm64_v8a
  py310-none-android_18_arm64_v8a
  py310-none-android_17_arm64_v8a
  py310-none-android_16_arm64_v8a
  py39-none-android_arm64_v8a
  py39-none-android_24_arm64_v8a
  py39-none-android_23_arm64_v8a
  py39-none-android_22_arm64_v8a
  py39-none-android_21_arm64_v8a
  py39-none-android_20_arm64_v8a
  py39-none-android_19_arm64_v8a
  py39-none-android_18_arm64_v8a
  py39-none-android_17_arm64_v8a
  py39-none-android_16_arm64_v8a
  py38-none-android_arm64_v8a
  py38-none-android_24_arm64_v8a
  py38-none-android_23_arm64_v8a
  py38-none-android_22_arm64_v8a
  py38-none-android_21_arm64_v8a
  py38-none-android_20_arm64_v8a
  py38-none-android_19_arm64_v8a
  py38-none-android_18_arm64_v8a
  py38-none-android_17_arm64_v8a
  py38-none-android_16_arm64_v8a
  py37-none-android_arm64_v8a
  py37-none-android_24_arm64_v8a
  py37-none-android_23_arm64_v8a
  py37-none-android_22_arm64_v8a
  py37-none-android_21_arm64_v8a
  py37-none-android_20_arm64_v8a
  py37-none-android_19_arm64_v8a
  py37-none-android_18_arm64_v8a
  py37-none-android_17_arm64_v8a
  py37-none-android_16_arm64_v8a
  py36-none-android_arm64_v8a
  py36-none-android_24_arm64_v8a
  py36-none-android_23_arm64_v8a
  py36-none-android_22_arm64_v8a
  py36-none-android_21_arm64_v8a
  py36-none-android_20_arm64_v8a
  py36-none-android_19_arm64_v8a
  py36-none-android_18_arm64_v8a
  py36-none-android_17_arm64_v8a
  py36-none-android_16_arm64_v8a
  py35-none-android_arm64_v8a
  py35-none-android_24_arm64_v8a
  py35-none-android_23_arm64_v8a
  py35-none-android_22_arm64_v8a
  py35-none-android_21_arm64_v8a
  py35-none-android_20_arm64_v8a
  py35-none-android_19_arm64_v8a
  py35-none-android_18_arm64_v8a
  py35-none-android_17_arm64_v8a
  py35-none-android_16_arm64_v8a
  py34-none-android_arm64_v8a
  py34-none-android_24_arm64_v8a
  py34-none-android_23_arm64_v8a
  py34-none-android_22_arm64_v8a
  py34-none-android_21_arm64_v8a
  py34-none-android_20_arm64_v8a
  py34-none-android_19_arm64_v8a
  py34-none-android_18_arm64_v8a
  py34-none-android_17_arm64_v8a
  py34-none-android_16_arm64_v8a
  py33-none-android_arm64_v8a
  py33-none-android_24_arm64_v8a
  py33-none-android_23_arm64_v8a
  py33-none-android_22_arm64_v8a
  py33-none-android_21_arm64_v8a
  py33-none-android_20_arm64_v8a
  py33-none-android_19_arm64_v8a
  py33-none-android_18_arm64_v8a
  py33-none-android_17_arm64_v8a
  py33-none-android_16_arm64_v8a
  py32-none-android_arm64_v8a
  py32-none-android_24_arm64_v8a
  py32-none-android_23_arm64_v8a
  py32-none-android_22_arm64_v8a
  py32-none-android_21_arm64_v8a
  py32-none-android_20_arm64_v8a
  py32-none-android_19_arm64_v8a
  py32-none-android_18_arm64_v8a
  py32-none-android_17_arm64_v8a
  py32-none-android_16_arm64_v8a
  py31-none-android_arm64_v8a
  py31-none-android_24_arm64_v8a
  py31-none-android_23_arm64_v8a
  py31-none-android_22_arm64_v8a
  py31-none-android_21_arm64_v8a
  py31-none-android_20_arm64_v8a
  py31-none-android_19_arm64_v8a
  py31-none-android_18_arm64_v8a
  py31-none-android_17_arm64_v8a
  py31-none-android_16_arm64_v8a
  py30-none-android_arm64_v8a
  py30-none-android_24_arm64_v8a
  py30-none-android_23_arm64_v8a
  py30-none-android_22_arm64_v8a
  py30-none-android_21_arm64_v8a
  py30-none-android_20_arm64_v8a
  py30-none-android_19_arm64_v8a
  py30-none-android_18_arm64_v8a
  py30-none-android_17_arm64_v8a
  py30-none-android_16_arm64_v8a
  cp314-none-any
  py314-none-any
  py3-none-any
  py313-none-any
  py312-none-any
  py311-none-any
  py310-none-any
  py39-none-any
  py38-none-any
  py37-none-any
  py36-none-any
  py35-none-any
  py34-none-any
  py33-none-any
  py32-none-any
  py31-none-any
  py30-none-any

@messense

messense commented Aug 3, 2026

Copy link
Copy Markdown
Member

@Benjamin-Loison getprop ro.build.version.sdk shows 32 but pip can accept as low as 16, could you also check clang -dumpmachine, and rebuild with export ANDROID_API_LEVEL=16?

@Benjamin-Loison

Copy link
Copy Markdown

I had struggle establishing my Fairphone 4 environment for tens of minutes, so if you are fine with it, the following continues the investigation with Virtual Machine Manager LineageOS 23.0 virtual machine Termux:

Personal notes:

termux/termux-docker:

getprop
/data/data/com.termux/files/usr/bin/getprop: 3: exec: /system/bin/getprop: not found
Environment setup:
pip install pydantic-core
Output:
Collecting pydantic-core
  Using cached pydantic_core-2.47.0.tar.gz (476 kB)
  Installing build dependencies ... error
  error: subprocess-exited-with-error
  
  × installing build dependencies for pydantic-core did not run successfully.
  │ exit code: 1
  ╰─> [31 lines of output]
      Collecting maturin<2,>=1.13.3
        Using cached maturin-1.14.1.tar.gz (369 kB)
        Installing build dependencies: started
        Installing build dependencies: finished with status 'done'
        Getting requirements to build wheel: started
        Getting requirements to build wheel: finished with status 'done'
        Installing backend dependencies: started
        Installing backend dependencies: finished with status 'done'
        Preparing metadata (pyproject.toml): started
        Preparing metadata (pyproject.toml): finished with status 'error'
        error: subprocess-exited-with-error
      
        × Preparing metadata (pyproject.toml) did not run successfully.
        │ exit code: 1
        ╰─> [6 lines of output]
            /data/data/com.termux/files/usr/tmp/pip-build-env-m0mep9ya/overlay/lib/python3.14/site-packages/setuptools/_vendor/wheel/bdist_wheel.py:4: FutureWarning: The 'wheel' package is no longer the canonical location of the 'bdist_wheel' command, and will be removed in a future release. Please update to setuptools v70.1 or later which contains an integrated version of this command.
              warn(
            Python reports SOABI: cpython-314-x86_64-linux-android
            Computed rustc target triple: x86_64-unknown-linux-android
            Target triple not supported by rustup: x86_64-unknown-linux-android
            Rust not found, installing into a temporary directory
            [end of output]
      
        note: This error originates from a subprocess, and is likely not a problem with pip.
      error: metadata-generation-failed
      
      × Encountered error while generating package metadata.
      ╰─> maturin
      
      note: This is an issue with the package mentioned above, not pip.
      hint: See above for details.
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed to build 'pydantic-core' when installing build dependencies for pydantic-core
apt install -y rustc
Output:
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
E: Unable to locate package rustc
apt install -y rustup
Output:
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
E: Unable to locate package rustup
apt install -y rust
Output:
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  libandroid-execinfo rust-std-x86-64-linux-android
Suggested packages:
  rust-analyzer
The following NEW packages will be installed:
  libandroid-execinfo rust rust-std-x86-64-linux-android
0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
Need to get 136 MB of archives.
After this operation, 619 MB of additional disk space will be used.
Get:1 https://packages-cf.termux.dev/apt/termux-main stable/main x86_64 libandroid-execinfo x86_64 0.1-3 [15.2 kB]
Get:2 https://packages-cf.termux.dev/apt/termux-main stable/main x86_64 rust-std-x86-64-linux-android x86_64 1.97.1 [4698 kB]
Get:3 https://packages-cf.termux.dev/apt/termux-main stable/main x86_64 rust x86_64 1.97.1 [131 MB]
Fetched 136 MB in 6s (20.9 MB/s)                                                                                                                 
Selecting previously unselected package libandroid-execinfo.
(Reading database ... 16280 files and directories currently installed.)
Preparing to unpack .../libandroid-execinfo_0.1-3_x86%5f64.deb ...
Unpacking libandroid-execinfo (0.1-3) ...
Selecting previously unselected package rust-std-x86-64-linux-android.
Preparing to unpack .../rust-std-x86-64-linux-android_1.97.1_x86%5f64.deb ...
Unpacking rust-std-x86-64-linux-android (1.97.1) ...
Selecting previously unselected package rust.
Preparing to unpack .../rust_1.97.1_x86%5f64.deb ...
Unpacking rust (1.97.1) ...
Setting up libandroid-execinfo (0.1-3) ...
Setting up rust-std-x86-64-linux-android (1.97.1) ...
Setting up rust (1.97.1) ...
time pip install --verbose pydantic-core

output.txt

This output may not be the right one.

time pip install pydantic-core
Output:
Collecting pydantic-core
  Using cached pydantic_core-2.47.0.tar.gz (476 kB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... error
  error: subprocess-exited-with-error
  
  × Preparing metadata (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [9 lines of output]
      🍹 Building a mixed python/rust project
      🐍 Found CPython 3.14 at /data/data/com.termux/files/usr/bin/python3.14
      🔗 Found pyo3 bindings
      📡 Using build options bindings from pyproject.toml
      💥 maturin failed
        Caused by: Failed to determine Android API level. Please set the ANDROID_API_LEVEL environment variable.
      Error running maturin: Command '['maturin', 'pep517', 'write-dist-info', '--metadata-directory', '/data/data/com.termux/files/usr/tmp/pip-modern-metadata-sepjamfu', '--interpreter', '/data/data/com.termux/files/usr/bin/python3.14']' returned non-zero exit status 1.
      Checking for Rust toolchain....
      Running `maturin pep517 write-dist-info --metadata-directory /data/data/com.termux/files/usr/tmp/pip-modern-metadata-sepjamfu --interpreter /data/data/com.termux/files/usr/bin/python3.14`
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed

× Encountered error while generating package metadata.
╰─> pydantic-core

note: This is an issue with the package mentioned above, not pip.
hint: See above for details.

real	0m1.467s
user	0m1.160s
sys	0m0.242s

So I reproduce the mentioned error.

export ANDROID_API_LEVEL=16
pip install --verbose pydantic-core
Output:
Using pip 26.2 from /data/data/com.termux/files/usr/lib/python3.14/site-packages/pip (python 3.14)
Collecting pydantic-core
  Using cached pydantic_core-2.47.0.tar.gz (476 kB)
  Running command installing build dependencies for pydantic-core
  Using pip 26.2 from /data/data/com.termux/files/usr/lib/python3.14/site-packages/pip (python 3.14)
  Collecting maturin<2,>=1.13.3
    Using cached maturin-1.14.1-cp314-cp314-android_24_x86_64.whl
  Installing collected packages: maturin
  Successfully installed maturin-1.14.1
  Installing build dependencies ... done
  Running command Getting requirements to build wheel
  Getting requirements to build wheel ... done
  Running command Preparing metadata (pyproject.toml)
  🍹 Building a mixed python/rust project
  🐍 Found CPython 3.14 at /data/data/com.termux/files/usr/bin/python3.14
  🔗 Found pyo3 bindings
  📡 Using build options bindings from pyproject.toml
  pydantic_core-2.47.0.dist-info
  Checking for Rust toolchain....
  Running `maturin pep517 write-dist-info --metadata-directory /data/data/com.termux/files/usr/tmp/pip-modern-metadata-0mv0yj22 --interpreter /data/data/com.termux/files/usr/bin/python3.14`
  Preparing metadata (pyproject.toml) ... done
Collecting typing-extensions>=4.14.1 (from pydantic-core)
  Obtaining dependency information for typing-extensions>=4.14.1 from https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl.metadata
  Using cached typing_extensions-4.16.0-py3-none-any.whl.metadata (3.3 kB)
Using cached typing_extensions-4.16.0-py3-none-any.whl (45 kB)
Building wheels for collected packages: pydantic-core
  Running command Building wheel for pydantic-core (pyproject.toml)
  Running `maturin pep517 build-wheel -i /data/data/com.termux/files/usr/bin/python3.14 --compatibility off`
  🍹 Building a mixed python/rust project
  🐍 Found CPython 3.14 at /data/data/com.termux/files/usr/bin/python3.14
  🔗 Found pyo3 bindings
  📡 Using build options bindings from pyproject.toml
     Compiling proc-macro2 v1.0.86
     Compiling quote v1.0.44
     Compiling unicode-ident v1.0.12
     Compiling target-lexicon v0.13.4
     Compiling python3-dll-a v0.2.14
     Compiling stable_deref_trait v1.2.0
     Compiling litemap v0.7.3
     Compiling writeable v0.5.5
     Compiling heck v0.5.0
     Compiling autocfg v1.3.0
     Compiling libc v0.2.185
     Compiling smallvec v1.15.1
     Compiling version_check v0.9.5
     Compiling icu_locid_transform_data v1.5.0
     Compiling static_assertions v1.1.0
     Compiling icu_properties_data v1.5.0
     Compiling lexical-util v1.0.6
     Compiling num-traits v0.2.19
     Compiling utf8_iter v1.0.4
     Compiling getrandom v0.3.3
     Compiling memchr v2.7.4
     Compiling write16 v1.0.0
     Compiling serde_core v1.0.228
     Compiling pyo3-build-config v0.28.3
     Compiling utf16_iter v1.0.5
     Compiling syn v2.0.82
     Compiling icu_normalizer_data v1.5.0
     Compiling zerocopy v0.8.25
     Compiling radium v0.7.0
     Compiling ahash v0.8.12
     Compiling cfg-if v1.0.0
     Compiling lexical-parse-integer v1.0.5
     Compiling once_cell v1.21.3
     Compiling tap v1.0.1
     Compiling zmij v1.0.6
     Compiling wyz v0.5.1
     Compiling lexical-parse-float v1.0.5
     Compiling num-integer v0.1.46
     Compiling aho-corasick v1.1.3
     Compiling num-bigint v0.4.6
     Compiling serde v1.0.228
     Compiling foldhash v0.2.0
     Compiling funty v2.0.0
     Compiling regex-syntax v0.8.5
     Compiling pyo3-ffi v0.28.3
     Compiling pyo3-macros-backend v0.28.3
     Compiling pyo3 v0.28.3
     Compiling jiter v0.14.0
     Compiling equivalent v1.0.2
     Compiling allocator-api2 v0.2.21
     Compiling serde_json v1.0.149
     Compiling percent-encoding v2.3.2
     Compiling form_urlencoded v1.2.2
     Compiling hashbrown v0.16.1
     Compiling bitvec v1.0.1
     Compiling pydantic-core v2.47.0 (/data/data/com.termux/files/usr/tmp/pip-install-6dnsass4/pydantic-core_f8a7242e04314c7b8c06f4ded0dc1a9a)
     Compiling regex-automata v0.4.13
     Compiling synstructure v0.13.1
     Compiling itoa v1.0.11
     Compiling lru v0.16.3
     Compiling hex v0.4.3
     Compiling uuid v1.23.0
     Compiling bias's v0.22.1
     Compiling zerofrom-derive v0.1.4
     Compiling yoke-derive v0.7.4
     Compiling zerovec-derive v0.10.3
     Compiling displaydoc v0.2.5
     Compiling icu_provider_macros v1.5.0
     Compiling strum_macros v0.27.2
     Compiling serde_derive v1.0.228
     Compiling regex v1.12.3
     Compiling enum_dispatch v0.3.13
     Compiling zerofrom v0.1.4
     Compiling yoke v0.7.4
     Compiling zerovec v0.10.4
     Compiling pyo3-macros v0.28.3
     Compiling strum v0.27.2
     Compiling speedate v0.17.0
     Compiling tinystr v0.7.6
     Compiling icu_collections v1.5.0
     Compiling icu_locid v1.5.0
     Compiling icu_provider v1.5.0
     Compiling icu_locid_transform v1.5.0
     Compiling icu_properties v1.5.1
     Compiling icu_normalizer v1.5.0
     Compiling idna_adapter v1.2.0
     Compiling idna v1.1.0
     Compiling url v2.5.8
      Finished `release` profile [optimized] target(s) in 1m 21s
  📦 Built wheel for CPython 3.14 to /data/data/com.termux/files/usr/tmp/pip-install-6dnsass4/pydantic-core_f8a7242e04314c7b8c06f4ded0dc1a9a/target/wheels/pydantic_core-2.47.0-cp314-cp314-android_16_x86_64.whl
  /data/data/com.termux/files/usr/tmp/pip-install-6dnsass4/pydantic-core_f8a7242e04314c7b8c06f4ded0dc1a9a/target/wheels/pydantic_core-2.47.0-cp314-cp314-android_16_x86_64.whl
  Building wheel for pydantic-core (pyproject.toml) ... done
  Created wheel for pydantic-core: filename=pydantic_core-2.47.0-cp314-cp314-android_16_x86_64.whl size=2100856 sha256=809bdd663436c7537d0aef122cb2c765f876118d085b2c776cb999471c583954
  Stored in directory: /data/data/com.termux/files/home/.cache/pip/wheels/76/ee/b9/cc90fa078cef82db031be8697c51b9163a1e00ef1a0039f205
Successfully built pydantic-core
Installing collected packages: typing-extensions, pydantic-core
Successfully installed pydantic-core-2.47.0 typing-extensions-4.16.0

real	1m23.530s
user	2m30.962s
sys	0m17.951
getprop ro.build.version.sdk
36
clang -dumpmachine
x86_64-unknown-linux-android24
python3 -m pip debug --verbose
Output:
WARNING: This command is only meant for debugging. Do not use this with automation for parsing and getting these details, since the output and options of this command may change without notice.
pip version: pip 26.2 from /data/data/com.termux/files/usr/lib/python3.14/site-packages/pip (python 3.14)
sys.version: 3.14.6 (main, Jul  3 2026, 19:52:10) [Clang 21.0.0 (https://android.googlesource.com/toolchain/llvm-project 5e96669f0
sys.executable: /data/data/com.termux/files/usr/bin/python3
sys.getdefaultencoding: utf-8
sys.getfilesystemencoding: utf-8
locale.getencoding: utf-8
sys.platform: android
sys.implementation:
  name: cpython
'cert' config value: global
REQUESTS_CA_BUNDLE: None
CURL_CA_BUNDLE: None
pip._vendor.certifi.where(): /data/data/com.termux/files/usr/lib/python3.14/site-packages/pip/_vendor/certifi/cacert.pem
pip._vendor.DEBUNDLED: False
vendored library versions:
  CacheControl==0.14.4 (Unable to locate actual module version, using vendor.txt specified version)
  distlib==0.4.2
  distro==1.9.0
  msgpack==1.1.2
  packaging==26.2
  platformdirs==4.10.0
  pyproject-hooks==1.2.0
  requests==2.34.2
  certifi==2026.06.17
  idna==3.18
  urllib3==2.7.0
  rich==14.2.0 (Unable to locate actual module version, using vendor.txt specified version)
  pygments==2.20.0
  resolvelib==1.2.1
  setuptools==70.3.0 (Unable to locate actual module version, using vendor.txt specified version)
  tomli==2.4.1
  tomli-w==1.2.0
  truststore==0.10.4
Compatible tags: 327
  cp314-cp314-android_x86_64
  cp314-cp314-android_24_x86_64
  cp314-cp314-android_23_x86_64
  cp314-cp314-android_22_x86_64
  cp314-cp314-android_21_x86_64
  cp314-cp314-android_20_x86_64
  cp314-cp314-android_19_x86_64
  cp314-cp314-android_18_x86_64
  cp314-cp314-android_17_x86_64
  cp314-cp314-android_16_x86_64
  cp314-abi3-android_x86_64
  cp314-abi3-android_24_x86_64
  cp314-abi3-android_23_x86_64
  cp314-abi3-android_22_x86_64
  cp314-abi3-android_21_x86_64
  cp314-abi3-android_20_x86_64
  cp314-abi3-android_19_x86_64
  cp314-abi3-android_18_x86_64
  cp314-abi3-android_17_x86_64
  cp314-abi3-android_16_x86_64
  cp314-none-android_x86_64
  cp314-none-android_24_x86_64
  cp314-none-android_23_x86_64
  cp314-none-android_22_x86_64
  cp314-none-android_21_x86_64
  cp314-none-android_20_x86_64
  cp314-none-android_19_x86_64
  cp314-none-android_18_x86_64
  cp314-none-android_17_x86_64
  cp314-none-android_16_x86_64
  cp313-abi3-android_x86_64
  cp313-abi3-android_24_x86_64
  cp313-abi3-android_23_x86_64
  cp313-abi3-android_22_x86_64
  cp313-abi3-android_21_x86_64
  cp313-abi3-android_20_x86_64
  cp313-abi3-android_19_x86_64
  cp313-abi3-android_18_x86_64
  cp313-abi3-android_17_x86_64
  cp313-abi3-android_16_x86_64
  cp312-abi3-android_x86_64
  cp312-abi3-android_24_x86_64
  cp312-abi3-android_23_x86_64
  cp312-abi3-android_22_x86_64
  cp312-abi3-android_21_x86_64
  cp312-abi3-android_20_x86_64
  cp312-abi3-android_19_x86_64
  cp312-abi3-android_18_x86_64
  cp312-abi3-android_17_x86_64
  cp312-abi3-android_16_x86_64
  cp311-abi3-android_x86_64
  cp311-abi3-android_24_x86_64
  cp311-abi3-android_23_x86_64
  cp311-abi3-android_22_x86_64
  cp311-abi3-android_21_x86_64
  cp311-abi3-android_20_x86_64
  cp311-abi3-android_19_x86_64
  cp311-abi3-android_18_x86_64
  cp311-abi3-android_17_x86_64
  cp311-abi3-android_16_x86_64
  cp310-abi3-android_x86_64
  cp310-abi3-android_24_x86_64
  cp310-abi3-android_23_x86_64
  cp310-abi3-android_22_x86_64
  cp310-abi3-android_21_x86_64
  cp310-abi3-android_20_x86_64
  cp310-abi3-android_19_x86_64
  cp310-abi3-android_18_x86_64
  cp310-abi3-android_17_x86_64
  cp310-abi3-android_16_x86_64
  cp39-abi3-android_x86_64
  cp39-abi3-android_24_x86_64
  cp39-abi3-android_23_x86_64
  cp39-abi3-android_22_x86_64
  cp39-abi3-android_21_x86_64
  cp39-abi3-android_20_x86_64
  cp39-abi3-android_19_x86_64
  cp39-abi3-android_18_x86_64
  cp39-abi3-android_17_x86_64
  cp39-abi3-android_16_x86_64
  cp38-abi3-android_x86_64
  cp38-abi3-android_24_x86_64
  cp38-abi3-android_23_x86_64
  cp38-abi3-android_22_x86_64
  cp38-abi3-android_21_x86_64
  cp38-abi3-android_20_x86_64
  cp38-abi3-android_19_x86_64
  cp38-abi3-android_18_x86_64
  cp38-abi3-android_17_x86_64
  cp38-abi3-android_16_x86_64
  cp37-abi3-android_x86_64
  cp37-abi3-android_24_x86_64
  cp37-abi3-android_23_x86_64
  cp37-abi3-android_22_x86_64
  cp37-abi3-android_21_x86_64
  cp37-abi3-android_20_x86_64
  cp37-abi3-android_19_x86_64
  cp37-abi3-android_18_x86_64
  cp37-abi3-android_17_x86_64
  cp37-abi3-android_16_x86_64
  cp36-abi3-android_x86_64
  cp36-abi3-android_24_x86_64
  cp36-abi3-android_23_x86_64
  cp36-abi3-android_22_x86_64
  cp36-abi3-android_21_x86_64
  cp36-abi3-android_20_x86_64
  cp36-abi3-android_19_x86_64
  cp36-abi3-android_18_x86_64
  cp36-abi3-android_17_x86_64
  cp36-abi3-android_16_x86_64
  cp35-abi3-android_x86_64
  cp35-abi3-android_24_x86_64
  cp35-abi3-android_23_x86_64
  cp35-abi3-android_22_x86_64
  cp35-abi3-android_21_x86_64
  cp35-abi3-android_20_x86_64
  cp35-abi3-android_19_x86_64
  cp35-abi3-android_18_x86_64
  cp35-abi3-android_17_x86_64
  cp35-abi3-android_16_x86_64
  cp34-abi3-android_x86_64
  cp34-abi3-android_24_x86_64
  cp34-abi3-android_23_x86_64
  cp34-abi3-android_22_x86_64
  cp34-abi3-android_21_x86_64
  cp34-abi3-android_20_x86_64
  cp34-abi3-android_19_x86_64
  cp34-abi3-android_18_x86_64
  cp34-abi3-android_17_x86_64
  cp34-abi3-android_16_x86_64
  cp33-abi3-android_x86_64
  cp33-abi3-android_24_x86_64
  cp33-abi3-android_23_x86_64
  cp33-abi3-android_22_x86_64
  cp33-abi3-android_21_x86_64
  cp33-abi3-android_20_x86_64
  cp33-abi3-android_19_x86_64
  cp33-abi3-android_18_x86_64
  cp33-abi3-android_17_x86_64
  cp33-abi3-android_16_x86_64
  cp32-abi3-android_x86_64
  cp32-abi3-android_24_x86_64
  cp32-abi3-android_23_x86_64
  cp32-abi3-android_22_x86_64
  cp32-abi3-android_21_x86_64
  cp32-abi3-android_20_x86_64
  cp32-abi3-android_19_x86_64
  cp32-abi3-android_18_x86_64
  cp32-abi3-android_17_x86_64
  cp32-abi3-android_16_x86_64
  py314-none-android_x86_64
  py314-none-android_24_x86_64
  py314-none-android_23_x86_64
  py314-none-android_22_x86_64
  py314-none-android_21_x86_64
  py314-none-android_20_x86_64
  py314-none-android_19_x86_64
  py314-none-android_18_x86_64
  py314-none-android_17_x86_64
  py314-none-android_16_x86_64
  py3-none-android_x86_64
  py3-none-android_24_x86_64
  py3-none-android_23_x86_64
  py3-none-android_22_x86_64
  py3-none-android_21_x86_64
  py3-none-android_20_x86_64
  py3-none-android_19_x86_64
  py3-none-android_18_x86_64
  py3-none-android_17_x86_64
  py3-none-android_16_x86_64
  py313-none-android_x86_64
  py313-none-android_24_x86_64
  py313-none-android_23_x86_64
  py313-none-android_22_x86_64
  py313-none-android_21_x86_64
  py313-none-android_20_x86_64
  py313-none-android_19_x86_64
  py313-none-android_18_x86_64
  py313-none-android_17_x86_64
  py313-none-android_16_x86_64
  py312-none-android_x86_64
  py312-none-android_24_x86_64
  py312-none-android_23_x86_64
  py312-none-android_22_x86_64
  py312-none-android_21_x86_64
  py312-none-android_20_x86_64
  py312-none-android_19_x86_64
  py312-none-android_18_x86_64
  py312-none-android_17_x86_64
  py312-none-android_16_x86_64
  py311-none-android_x86_64
  py311-none-android_24_x86_64
  py311-none-android_23_x86_64
  py311-none-android_22_x86_64
  py311-none-android_21_x86_64
  py311-none-android_20_x86_64
  py311-none-android_19_x86_64
  py311-none-android_18_x86_64
  py311-none-android_17_x86_64
  py311-none-android_16_x86_64
  py310-none-android_x86_64
  py310-none-android_24_x86_64
  py310-none-android_23_x86_64
  py310-none-android_22_x86_64
  py310-none-android_21_x86_64
  py310-none-android_20_x86_64
  py310-none-android_19_x86_64
  py310-none-android_18_x86_64
  py310-none-android_17_x86_64
  py310-none-android_16_x86_64
  py39-none-android_x86_64
  py39-none-android_24_x86_64
  py39-none-android_23_x86_64
  py39-none-android_22_x86_64
  py39-none-android_21_x86_64
  py39-none-android_20_x86_64
  py39-none-android_19_x86_64
  py39-none-android_18_x86_64
  py39-none-android_17_x86_64
  py39-none-android_16_x86_64
  py38-none-android_x86_64
  py38-none-android_24_x86_64
  py38-none-android_23_x86_64
  py38-none-android_22_x86_64
  py38-none-android_21_x86_64
  py38-none-android_20_x86_64
  py38-none-android_19_x86_64
  py38-none-android_18_x86_64
  py38-none-android_17_x86_64
  py38-none-android_16_x86_64
  py37-none-android_x86_64
  py37-none-android_24_x86_64
  py37-none-android_23_x86_64
  py37-none-android_22_x86_64
  py37-none-android_21_x86_64
  py37-none-android_20_x86_64
  py37-none-android_19_x86_64
  py37-none-android_18_x86_64
  py37-none-android_17_x86_64
  py37-none-android_16_x86_64
  py36-none-android_x86_64
  py36-none-android_24_x86_64
  py36-none-android_23_x86_64
  py36-none-android_22_x86_64
  py36-none-android_21_x86_64
  py36-none-android_20_x86_64
  py36-none-android_19_x86_64
  py36-none-android_18_x86_64
  py36-none-android_17_x86_64
  py36-none-android_16_x86_64
  py35-none-android_x86_64
  py35-none-android_24_x86_64
  py35-none-android_23_x86_64
  py35-none-android_22_x86_64
  py35-none-android_21_x86_64
  py35-none-android_20_x86_64
  py35-none-android_19_x86_64
  py35-none-android_18_x86_64
  py35-none-android_17_x86_64
  py35-none-android_16_x86_64
  py34-none-android_x86_64
  py34-none-android_24_x86_64
  py34-none-android_23_x86_64
  py34-none-android_22_x86_64
  py34-none-android_21_x86_64
  py34-none-android_20_x86_64
  py34-none-android_19_x86_64
  py34-none-android_18_x86_64
  py34-none-android_17_x86_64
  py34-none-android_16_x86_64
  py33-none-android_x86_64
  py33-none-android_24_x86_64
  py33-none-android_23_x86_64
  py33-none-android_22_x86_64
  py33-none-android_21_x86_64
  py33-none-android_20_x86_64
  py33-none-android_19_x86_64
  py33-none-android_18_x86_64
  py33-none-android_17_x86_64
  py33-none-android_16_x86_64
  py32-none-android_x86_64
  py32-none-android_24_x86_64
  py32-none-android_23_x86_64
  py32-none-android_22_x86_64
  py32-none-android_21_x86_64
  py32-none-android_20_x86_64
  py32-none-android_19_x86_64
  py32-none-android_18_x86_64
  py32-none-android_17_x86_64
  py32-none-android_16_x86_64
  py31-none-android_x86_64
  py31-none-android_24_x86_64
  py31-none-android_23_x86_64
  py31-none-android_22_x86_64
  py31-none-android_21_x86_64
  py31-none-android_20_x86_64
  py31-none-android_19_x86_64
  py31-none-android_18_x86_64
  py31-none-android_17_x86_64
  py31-none-android_16_x86_64
  py30-none-android_x86_64
  py30-none-android_24_x86_64
  py30-none-android_23_x86_64
  py30-none-android_22_x86_64
  py30-none-android_21_x86_64
  py30-none-android_20_x86_64
  py30-none-android_19_x86_64
  py30-none-android_18_x86_64
  py30-none-android_17_x86_64
  py30-none-android_16_x86_64
  cp314-none-any
  py314-none-any
  py3-none-any
  py313-none-any
  py312-none-any
  py311-none-any
  py310-none-any
  py39-none-any
  py38-none-any
  py37-none-any
  py36-none-any
  py35-none-any
  py34-none-any
  py33-none-any
  py32-none-any
  py31-none-any
  py30-none-any

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants