Spaces:
Paused
Paused
| FROM python:3.11.10-bookworm | |
| # 1. Системные зависимости | |
| ENV DEBIAN_FRONTEND=noninteractive | |
| RUN apt-get update && apt-get install -y \ | |
| wget unzip build-essential git pkg-config \ | |
| automake autoconf libtool zip sed \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # 2. Настройка NDK (r25c / API 30) | |
| ENV ANDROID_NDK_VERSION=r25c | |
| ENV ANDROID_API=30 | |
| ENV NDK_ROOT=/opt/android-ndk | |
| ENV ANDROID_NDK_ROOT=/opt/android-ndk | |
| ENV PATH=$NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH | |
| WORKDIR /opt | |
| RUN wget -q https://dl.google.com/android/repository/android-ndk-${ANDROID_NDK_VERSION}-linux.zip && \ | |
| unzip -q android-ndk-${ANDROID_NDK_VERSION}-linux.zip && \ | |
| mv android-ndk-${ANDROID_NDK_VERSION} android-ndk && \ | |
| rm android-ndk-${ANDROID_NDK_VERSION}-linux.zip | |
| # Инструменты компиляции | |
| ENV CC="aarch64-linux-android${ANDROID_API}-clang" | |
| ENV CXX="aarch64-linux-android${ANDROID_API}-clang++" | |
| ENV AR="llvm-ar" | |
| ENV RANLIB="llvm-ranlib" | |
| ENV STRIP="llvm-strip" | |
| ENV READELF="llvm-readelf" | |
| ENV PREFIX=/opt/android-libs | |
| RUN mkdir -p $PREFIX | |
| # 3. ZLIB (Static + fPIC) | |
| WORKDIR /build/zlib | |
| RUN wget -q https://zlib.net/zlib-1.3.1.tar.gz && tar -xf zlib-1.3.1.tar.gz && cd zlib-1.3.1 && \ | |
| CFLAGS="-fPIC" ./configure --prefix=$PREFIX --static && make -j4 install | |
| # 4. OpenSSL (Static + fPIC) | |
| # no-apps и no-tests обязательны, чтобы не пытаться запускать ARM на x86 | |
| WORKDIR /build/openssl | |
| RUN wget -q https://www.openssl.org/source/openssl-3.2.0.tar.gz && tar -xf openssl-3.2.0.tar.gz && cd openssl-3.2.0 && \ | |
| ./Configure android-arm64 -D__ANDROID_API__=${ANDROID_API} --prefix=$PREFIX \ | |
| no-shared no-apps no-tests no-docs -fPIC && \ | |
| make -j4 && make install_sw | |
| # 5. LibCurl (Static + fPIC) | |
| WORKDIR /build/curl | |
| RUN wget -q https://curl.se/download/curl-8.5.0.tar.gz && tar -xf curl-8.5.0.tar.gz && cd curl-8.5.0 && \ | |
| ./configure --host=aarch64-linux-android --prefix=$PREFIX --disable-shared --enable-static \ | |
| --with-openssl=$PREFIX --with-zlib=$PREFIX --disable-ldap \ | |
| CFLAGS="-fPIC -I$PREFIX/include" LDFLAGS="-L$PREFIX/lib" && \ | |
| make -j4 install | |
| # 6. СБОРКА РЕАЛЬНОГО PYTHON 3.11.10 ПОД АНДРОИД | |
| # Это нужно для получения правильной libpython3.11.so для линковки символов | |
| WORKDIR /opt/python-android | |
| RUN wget -q https://www.python.org/ftp/python/3.11.10/Python-3.11.10.tgz && tar -xf Python-3.11.10.tgz | |
| WORKDIR /opt/python-android/Python-3.11.10 | |
| RUN ./configure --host=aarch64-linux-android --build=x86_64-linux-gnu \ | |
| --with-build-python=python3 --enable-shared --without-ensurepip \ | |
| --disable-ipv6 ac_cv_file__dev_ptmx=no ac_cv_file__dev_ptc=no ac_cv_buggy_getaddrinfo=no \ | |
| CC="$CC" CXX="$CXX" AR="$AR" RANLIB="$RANLIB" READELF="$READELF" \ | |
| CFLAGS="-fPIC" CXXFLAGS="-fPIC" LDFLAGS="-fPIC" | |
| RUN make -j4 libpython3.11.so | |
| # 7. СБОРКА ПАКЕТОВ (WHEELS) | |
| WORKDIR /build/wheels | |
| RUN pip install wheel setuptools | |
| # Fake curl-config | |
| RUN echo '#!/bin/bash\ncase "$1" in --version) echo "libcurl 8.5.0";; --features) echo "SSL libz HTTPS";; --libs|--static-libs) echo "-L'$PREFIX'/lib -lcurl -lssl -lcrypto -lz";; --cflags) echo "-I'$PREFIX'/include -DANDROID";; --prefix) echo "'$PREFIX'";; *) exit 0;; esac' > /usr/bin/curl-config-android && chmod +x /usr/bin/curl-config-android | |
| # Скрипт сборки без сломанного флага --plat-name | |
| RUN echo '#!/bin/bash\n\ | |
| export CC="aarch64-linux-android'${ANDROID_API}'-clang"\n\ | |
| export PYTHON_ROOT="/opt/python-android/Python-3.11.10"\n\ | |
| # LDSHARED линкует pycurl напрямую к либе питона, чтобы разрешить _Py_NoneStruct\n\ | |
| export LDSHARED="'$CC' -shared -L$PYTHON_ROOT -lpython3.11"\n\ | |
| export CFLAGS="-I$PYTHON_ROOT/Include -I$PYTHON_ROOT -I'$PREFIX'/include -fPIC -DANDROID"\n\ | |
| export LDFLAGS="-L$PYTHON_ROOT -L'$PREFIX'/lib -lpython3.11 -lcurl -lssl -lcrypto -lz"\n\ | |
| \n\ | |
| echo "--- Сборка wget (Pure Python) ---"\n\ | |
| pip wheel wget --no-binary :all: --no-deps -w dist/\n\ | |
| \n\ | |
| echo "--- Сборка PyCryptodome (C-Extension) ---"\n\ | |
| pip wheel pycryptodome --no-binary :all: --no-deps -w dist/\n\ | |
| \n\ | |
| echo "--- Сборка PyCurl (C-Extension + Static Curl) ---"\n\ | |
| export PYCURL_CURL_CONFIG=/usr/bin/curl-config-android\n\ | |
| export PYCURL_SSL_LIBRARY=openssl\n\ | |
| pip wheel pycurl --no-binary :all: --no-deps -w dist/' > build.sh | |
| RUN chmod +x build.sh && ./build.sh | |
| # 8. ПЕРЕИМЕНОВАНИЕ И ПРОВЕРКА | |
| WORKDIR /output | |
| RUN cd /build/wheels/dist && \ | |
| for file in *.whl; do \ | |
| # Извлекаем имя и версию | |
| NAME=$(echo $file | cut -d"-" -f1) && \ | |
| VER=$(echo $file | cut -d"-" -f2) && \ | |
| # Формируем эталонный тег Chaquopy 3.11\n\ | |
| TAG="cp311-cp311-android_21_30_arm64_v8a" && \ | |
| mv "$file" "/output/${NAME}-${VER}-${TAG}.whl"; \ | |
| done | |
| # Проверка линковки pycurl.so (чтобы убедиться, что он видит libpython3.11.so) | |
| RUN echo "Checking dependencies of pycurl.so:" && \ | |
| unzip -p /output/pycurl-*.whl *.so > /tmp/pycurl.so && \ | |
| llvm-readelf -d /tmp/pycurl.so | grep "NEEDED" | |
| # 9. Выдача | |
| CMD ["python3", "-m", "http.server", "7860", "--directory", "/output"] | |