astral-sh / uv

An extremely fast Python package installer and resolver, written in Rust.
https://astral.sh/
Apache License 2.0
11.28k stars 307 forks source link

Termux on Android #2408

Open phanirithvij opened 1 month ago

phanirithvij commented 1 month ago

I tried installing on termux on Android but build failed. Can this platform Android be supported?

charbeljc commented 1 month ago

Hi, we are following the same path, here. From what I see, rye is installable with no glitches on Termux, failing at runtime to bootstrap itself due to the unavailability of uv.

cargo install --path crates/uv

fails at link stage:

[...] "/data/data/com.termux/files/usr/lib/rustlib/aarch64-linux-android/lib/libcompiler_builtins-d269850cd60e0323.rlib" \
  "-Wl,-Bdynamic" "-lgcc" "-lz" "-ldl" "-llog" "-lunwind" "-ldl" "-lm" "-lc" \
  "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" \
  "-L" "/data/data/com.termux/files/usr/lib/rustlib/aarch64-linux-android/lib" "-o" "/data/data/com.termux/files/home/Hack/uv/target/release/deps/uv-e66b0816d4199fc5" \
  "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-Wl,-O1" "-nodefaultlibs"
  = note: ld.lld: error: unable to find library -lgcc
          cc: error: linker command failed with exit code 1 (use -v to see invocation)

I guess ccis the culprit here...

Regards

charliermarsh commented 1 month ago

I haven't looked at it at all, but you could try --no-default-features --features flate2/rust_backend to reduce some native dependencies.

charbeljc commented 1 month ago

Hey, I did try another way, and just succeeded installing...

See https://stackoverflow.com/questions/68873570/how-do-i-fix-ld-error-unable-to-find-library-lgcc-when-cross-compiling-rust for details.

cd /data/data/com.termux/files/usr/lib
cat << EOF > libgcc.a
INPUT(-lunwind)
EOF
cd $UV_SOURCES
cargo install --path crates/uv

Bingo !

charbeljc commented 1 month ago

However, there is still work to be done here...

❯ uv venv
  × Querying Python at `/data/data/com.termux/files/usr/bin/python3` did not return the expected
  │ data: invalid value: integer `-1`, expected u16 with exit status: 0
  │ --- stdout:
  │ {"result": "success", "markers": {"implementation_name": "cpython", "implementation_version":
  │ "3.11.8", "os_name": "posix", "platform_machine": "aarch64", "platform_python_implementation":
  │ "CPython", "platform_release": "5.4.233-qgki-ge0ae3f4f4643", "platform_system": "Linux",
  │ "platform_version": "#1 SMP PREEMPT Thu Dec 14 04:24:04 UTC 2023 f2fs-hash:1e2949fb28",
  │ "python_full_version": "3.11.8", "python_version": "3.11", "sys_platform":
  │ "linux"}, "base_prefix": "/data/data/com.termux/files/usr", "base_exec_prefix":
  │ "/data/data/com.termux/files/usr", "prefix": "/data/data/com.termux/files/usr",
  │ "base_executable": "/data/data/com.termux/files/usr/bin/python3",
  │ "sys_executable": "/data/data/com.termux/files/usr/bin/python3", "stdlib":
  │ "/data/data/com.termux/files/usr/lib/python3.11", "scheme": {"platlib":
  │ "/data/data/com.termux/files/usr/lib/python3.11/site-packages", "purelib":
  │ "/data/data/com.termux/files/usr/lib/python3.11/site-packages", "include":
  │ "/data/data/com.termux/files/usr/include/python3.11", "scripts":
  │ "/data/data/com.termux/files/usr/bin", "data": "/data/data/com.termux/files/usr"},
  │ "virtualenv": {"purelib": "lib/python3.11/site-packages", "platlib":
  │ "lib/python3.11/site-packages", "include": "include/site/python3.11", "scripts": "bin",
  │ "data": ""}, "platform": {"os": {"name": "manylinux", "major": -1, "minor": -1}, "arch":
  │ "aarch64"}}
  │ --- stderr:

  │ ---
charbeljc commented 1 month ago

With something like that, uv goes further, trying to install fastapi.

diff --git a/crates/uv-interpreter/python/get_interpreter_info.py b/crates/uv-interpreter/python/get_interpreter_info.py
index a2c1e98b..210c8c6b 100644
--- a/crates/uv-interpreter/python/get_interpreter_info.py
+++ b/crates/uv-interpreter/python/get_interpreter_info.py
@@ -440,11 +440,16 @@ def get_operating_system_and_architecture():
                 "minor": musl_version[1],
             }
         elif glibc_version:
-            operating_system = {
-                "name": "manylinux",
-                "major": glibc_version[0],
-                "minor": glibc_version[1],
-            }
+            if glibc_version == (-1, -1) and architecture == "aarch64":
+                operating_system = {
+                    "name": "android",
+                }
+            else:
+                operating_system = {
+                    "name": "manylinux",
+                    "major": glibc_version[0],
+                    "minor": glibc_version[1],
+                }
         else:

Oh, and it even installed maturin from sources and trying to build _pydantic_core with it, right now ...

[...]
DEBUG Writing entrypoints name="pydantic"
DEBUG No data name="pydantic"
DEBUG Writing extra metadata name="pydantic"
DEBUG Writing record name="pydantic"
Installed 10 packages in 63ms
 + annotated-types==0.6.0
 + anyio==4.3.0
 + fastapi==0.110.0
 - hello==0.1.0 (from file:///data/data/com.termux/files/home/Hack/hello)
 + hello==0.1.0 (from file:///data/data/com.termux/files/home/Hack/hello)
 + idna==3.6
 + pydantic==2.6.4
 + pydantic-core==2.16.3
 + sniffio==1.3.1
 + starlette==0.36.3
 + typing-extensions==4.10.0

And python is failing to load fastapi.

❯ python
Python 3.11.8 (main, Feb 11 2024, 13:05:24) [Clang 17.0.2 (https://android.googlesource.com/toolchain/llvm-project d9f89f4d1 on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import fastapi
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/data/data/com.termux/files/home/Hack/hello/.venv/lib/python3.11/site-packages/fastapi/__init__.py", line 7, in <module>
    from .applications import FastAPI as FastAPI
  File "/data/data/com.termux/files/home/Hack/hello/.venv/lib/python3.11/site-packages/fastapi/applications.py", line 16, in <module>
    from fastapi import routing
  File "/data/data/com.termux/files/home/Hack/hello/.venv/lib/python3.11/site-packages/fastapi/routing.py", line 22, in <module>
    from fastapi import params
  File "/data/data/com.termux/files/home/Hack/hello/.venv/lib/python3.11/site-packages/fastapi/params.py", line 5, in <module>
    from fastapi.openapi.models import Example
  File "/data/data/com.termux/files/home/Hack/hello/.venv/lib/python3.11/site-packages/fastapi/openapi/models.py", line 4, in <module>
    from fastapi._compat import (
  File "/data/data/com.termux/files/home/Hack/hello/.venv/lib/python3.11/site-packages/fastapi/_compat.py", line 20, in <module>
    from fastapi.exceptions import RequestErrorModel
  File "/data/data/com.termux/files/home/Hack/hello/.venv/lib/python3.11/site-packages/fastapi/exceptions.py", line 3, in <module>
    from pydantic import BaseModel, create_model
  File "/data/data/com.termux/files/home/Hack/hello/.venv/lib/python3.11/site-packages/pydantic/__init__.py", line 383, in __getattr__
    module = import_module(module_name, package=package)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/data/com.termux/files/usr/lib/python3.11/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/data/com.termux/files/home/Hack/hello/.venv/lib/python3.11/site-packages/pydantic/main.py", line 14, in <module>
    from pydantic_core import PydanticUndefined
ImportError: cannot import name 'PydanticUndefined' from 'pydantic_core' (unknown location)
>>>

That's all for tonight :cat2: