MandreCompiler / Dockerfile
sterepando's picture
Update Dockerfile
e5c0e9b verified
raw
history blame
8.92 kB
FROM python:3.11-bookworm
# Устанавливаем зависимости.
# Добавлены ninja-build и gfortran, которые часто требуются для сборки numpy/scipy
RUN apt-get update && apt-get install -y \
wget unzip git build-essential pkg-config \
libffi-dev libssl-dev zlib1g-dev ncurses-dev \
libsqlite3-dev libreadline-dev libbz2-dev liblzma-dev \
uuid-dev curl \
cmake llvm clang \
perl ninja-build gfortran \
patchelf zip \
&& rm -rf /var/lib/apt/lists/*
# === НАСТРОЙКА ОКРУЖЕНИЯ (как в примере) ===
ENV WORK_DIR=/build
ENV OUTPUT_DIR=/app/wheels
ENV NDK_VERSION=r26b
ENV ANDROID_API=24
ENV ANDROID_ARCH=aarch64
ENV ANDROID_HOME=/opt/android-sdk
ENV NDK_HOME=/opt/android-ndk
ENV ANDROID_NDK_ROOT=/opt/android-ndk
ENV PYTHON_VERSION=3.11.9
ENV OPENSSL_VERSION=3.3.0
ENV RUSTUP_HOME=/opt/rust
ENV CARGO_HOME=/opt/rust
ENV PATH=$PATH:/opt/rust/bin
# === УСТАНОВКА RUST (Для pedalboard) ===
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
RUN rustup target add aarch64-linux-android
# === ПОДГОТОВКА PYTHON ИНСТРУМЕНТОВ ===
RUN pip install --upgrade pip && \
pip install --no-cache-dir \
Cython wheel setuptools poetry-core hatchling \
hatch-fancy-pypi-readme hatch-vcs flit-core \
expandvars maturin typing-extensions meson-python ninja
WORKDIR ${WORK_DIR}
# === УСТАНОВКА NDK ===
RUN wget -q https://dl.google.com/android/repository/android-ndk-${NDK_VERSION}-linux.zip && \
unzip -q android-ndk-${NDK_VERSION}-linux.zip && \
mv android-ndk-${NDK_VERSION} ${NDK_HOME} && \
rm android-ndk-${NDK_VERSION}-linux.zip
ENV TOOLCHAIN=${NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64
ENV PATH=${TOOLCHAIN}/bin:$PATH
ENV TARGET=${ANDROID_ARCH}-linux-android${ANDROID_API}
ENV CC="${TOOLCHAIN}/bin/${TARGET}-clang"
ENV CXX="${TOOLCHAIN}/bin/${TARGET}-clang++"
ENV AR="${TOOLCHAIN}/bin/llvm-ar"
ENV NM="${TOOLCHAIN}/bin/llvm-nm"
ENV LD="${TOOLCHAIN}/bin/ld"
ENV RANLIB="${TOOLCHAIN}/bin/llvm-ranlib"
ENV STRIP="${TOOLCHAIN}/bin/llvm-strip"
ENV READELF="${TOOLCHAIN}/bin/llvm-readelf"
ENV CFLAGS="-target ${TARGET} -fPIC -D__ANDROID__"
ENV CXXFLAGS="-target ${TARGET} -fPIC -D__ANDROID__"
ENV LDFLAGS="-target ${TARGET} -fPIC"
# === СБОРКА OPENSSL (Для зависимостей pedalboard/rust) ===
WORKDIR ${WORK_DIR}
RUN wget -q https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz && \
tar -xf openssl-${OPENSSL_VERSION}.tar.gz
WORKDIR ${WORK_DIR}/openssl-${OPENSSL_VERSION}
RUN ./Configure android-arm64 \
-D__ANDROID_API__=${ANDROID_API} \
--prefix=${WORK_DIR}/openssl-install \
--openssldir=${WORK_DIR}/openssl-install \
no-shared no-tests
RUN make -j$(nproc) && make install_sw
ENV OPENSSL_DIR=${WORK_DIR}/openssl-install
ENV OPENSSL_LIB_DIR=${OPENSSL_DIR}/lib64
ENV OPENSSL_INCLUDE_DIR=${OPENSSL_DIR}/include
ENV OPENSSL_STATIC=1
# === СБОРКА PYTHON (HOST) ДЛЯ ЗАГОЛОВКОВ ===
WORKDIR ${WORK_DIR}
RUN wget -q https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tgz && \
tar -xf Python-${PYTHON_VERSION}.tgz
WORKDIR ${WORK_DIR}/Python-${PYTHON_VERSION}
# Фейковые настройки конфигурации для кросс-компиляции
RUN echo "ac_cv_file__dev_ptmx=yes" > config.site && \
echo "ac_cv_file__dev_ptc=no" >> config.site && \
echo "ac_cv_func_wcsftime=no" >> config.site && \
echo "ac_cv_func_gethostbyname_r=no" >> config.site && \
echo "ac_cv_func_sendfile=no" >> config.site && \
echo "ac_cv_func_broken_mbstowcs=no" >> config.site && \
echo "ac_cv_func_wcscoll=no" >> config.site
RUN CONFIG_SITE=config.site ./configure \
CFLAGS="${CFLAGS}" \
LDFLAGS="${LDFLAGS}" \
--host=aarch64-linux-android \
--build=x86_64-linux-gnu \
--prefix=${WORK_DIR}/python-install \
--disable-ipv6 \
--enable-shared \
--without-ensurepip \
--with-build-python=/usr/local/bin/python3 \
--disable-test-modules \
--without-doc-strings \
--with-system-ffi=no \
--without-decimal \
--without-ctypes
RUN make -j$(nproc) libpython3.11.so || true
RUN make install -i
RUN mkdir -p ${WORK_DIR}/python-install/lib/python3.11
# Хак для sysconfigdata, чтобы setuptools думал, что мы на arm64
RUN find ${WORK_DIR}/Python-${PYTHON_VERSION} -name "_sysconfigdata*.py" -not -name "*x86_64*" \
-exec cp {} ${WORK_DIR}/python-install/lib/python3.11/_sysconfigdata__linux_aarch64-linux-android.py \;
RUN cp ${WORK_DIR}/python-install/lib/python3.11/_sysconfigdata__linux_aarch64-linux-android.py \
/usr/local/lib/python3.11/_sysconfigdata__linux_aarch64-linux-android.py
WORKDIR ${OUTPUT_DIR}
# === НАСТРОЙКИ RUST ДЛЯ КРОСС-КОМПИЛЯЦИИ ===
ENV CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="${CC}"
ENV CARGO_TARGET_AARCH64_LINUX_ANDROID_RUSTFLAGS="-C link-arg=-L${WORK_DIR}/python-install/lib -C link-arg=-lpython3.11 -L ${OPENSSL_LIB_DIR}"
# === СКРИПТ СБОРКИ ===
RUN echo "#!/bin/bash" > build.sh && \
echo "set -e" >> build.sh && \
echo "export PYTHON_ANDROID_HOME=${WORK_DIR}/python-install" >> build.sh && \
echo "export CFLAGS=\"${CFLAGS} -I\${PYTHON_ANDROID_HOME}/include/python3.11 -I${OPENSSL_INCLUDE_DIR}\"" >> build.sh && \
echo "export LDFLAGS=\"${LDFLAGS} -L\${PYTHON_ANDROID_HOME}/lib -L${OPENSSL_LIB_DIR}\"" >> build.sh && \
echo "export LDSHARED=\"${CC} -shared\"" >> build.sh && \
echo "export _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata__linux_aarch64-linux-android" >> build.sh && \
echo "export _PYTHON_HOST_PLATFORM=linux-aarch64" >> build.sh && \
# Переменные для PyO3 (Pedalboard)
echo "export PYO3_CROSS_LIB_DIR=${WORK_DIR}/python-install/lib" >> build.sh && \
echo "export PYO3_CROSS_INCLUDE_DIR=${WORK_DIR}/python-install/include/python3.11" >> build.sh && \
echo "export PYO3_CROSS_PYTHON_VERSION=3.11" >> build.sh && \
echo "export CARGO_BUILD_TARGET=aarch64-linux-android" >> build.sh && \
echo "export PYO3_NO_PYTHON_VERSION_CHECK=1" >> build.sh && \
# Переменные для OpenSSL crate
echo "export AARCH64_LINUX_ANDROID_OPENSSL_DIR=${OPENSSL_DIR}" >> build.sh && \
echo "export AARCH64_LINUX_ANDROID_OPENSSL_LIB_DIR=${OPENSSL_LIB_DIR}" >> build.sh && \
echo "export AARCH64_LINUX_ANDROID_OPENSSL_INCLUDE_DIR=${OPENSSL_INCLUDE_DIR}" >> build.sh && \
echo "export OPENSSL_STATIC=1" >> build.sh && \
# === СПЕЦИФИКА NUMPY ===
# Отключаем поиск внешних библиотек BLAS/LAPACK, чтобы избежать ошибок линковки.
# Numpy соберется с упрощенной линейной алгеброй.
echo "export NPY_BLAS_ORDER=''" >> build.sh && \
echo "export NPY_LAPACK_ORDER=''" >> build.sh && \
echo "export NPY_DISABLE_SVML=1" >> build.sh && \
echo "" >> build.sh && \
echo "echo 'Starting Build for Numpy and Pedalboard...'" >> build.sh && \
# Сборка. Используем --no-deps, чтобы собирать колеса по одному (или вместе, но контролируемо)
echo "pip wheel numpy pedalboard --wheel-dir=${OUTPUT_DIR} --no-binary=:all: --no-build-isolation -v" >> build.sh && \
chmod +x build.sh
RUN ./build.sh
# === POST-PROCESSING (PATCHELF) ===
# Патчим зависимость от libpython3.11.so.1.0 -> libpython3.11.so
RUN echo "Patching wheels..." && \
for whl in *.whl; do \
echo "Processing $whl..."; \
mkdir -p tmp_wheel; \
unzip -q "$whl" -d tmp_wheel; \
find tmp_wheel -name "*.so" | while read so_file; do \
if patchelf --print-needed "$so_file" | grep -q "libpython3.11.so.1.0"; then \
echo " -> Patching $so_file"; \
patchelf --replace-needed "libpython3.11.so.1.0" "libpython3.11.so" "$so_file"; \
fi; \
done; \
cd tmp_wheel; \
zip -r -q "../$whl" .; \
cd ..; \
rm -rf tmp_wheel; \
done
# === ПЕРЕИМЕНОВАНИЕ В ANDROID TAG ===
RUN for f in *.whl; do \
if [ -f "$f" ]; then \
new_name=$(echo "$f" | sed 's/linux_aarch64/android_24_arm64_v8a/g'); \
if [ "$f" != "$new_name" ]; then \
mv "$f" "$new_name"; \
fi \
fi \
done
# === ГЕНЕРАЦИЯ ИНДЕКСА ===
RUN echo "<html><head><title>Android Wheels</title></head><body>" > index.html && \
echo "<h1>Numpy & Pedalboard Wheels (API 24, ARM64)</h1><ul>" >> index.html && \
find . -name "*.whl" -printf "<li><a href=\"%P\">%P</a></li>\n" | sort >> index.html && \
echo "</ul></body></html>" >> index.html
EXPOSE 7860
CMD ["python3", "-m", "http.server", "7860"]