sterepando commited on
Commit
f179f42
·
verified ·
1 Parent(s): e5c0e9b

Update Dockerfile

Browse files
Files changed (1) hide show
  1. Dockerfile +101 -198
Dockerfile CHANGED
@@ -1,205 +1,108 @@
1
- FROM python:3.11-bookworm
2
 
3
- # Устанавливаем зависимости.
4
- # Добавлены ninja-build и gfortran, которые часто требуются для сборки numpy/scipy
5
  RUN apt-get update && apt-get install -y \
6
- wget unzip git build-essential pkg-config \
7
- libffi-dev libssl-dev zlib1g-dev ncurses-dev \
8
- libsqlite3-dev libreadline-dev libbz2-dev liblzma-dev \
9
- uuid-dev curl \
10
- cmake llvm clang \
11
- perl ninja-build gfortran \
12
- patchelf zip \
 
 
 
13
  && rm -rf /var/lib/apt/lists/*
14
 
15
- # === НАСТРОЙКА ОКРУЖЕНИЯ (как в примере) ===
16
- ENV WORK_DIR=/build
17
- ENV OUTPUT_DIR=/app/wheels
18
- ENV NDK_VERSION=r26b
19
- ENV ANDROID_API=24
20
- ENV ANDROID_ARCH=aarch64
21
- ENV ANDROID_HOME=/opt/android-sdk
22
- ENV NDK_HOME=/opt/android-ndk
23
- ENV ANDROID_NDK_ROOT=/opt/android-ndk
24
- ENV PYTHON_VERSION=3.11.9
25
- ENV OPENSSL_VERSION=3.3.0
26
- ENV RUSTUP_HOME=/opt/rust
27
- ENV CARGO_HOME=/opt/rust
28
- ENV PATH=$PATH:/opt/rust/bin
29
-
30
- # === УСТАНОВКА RUST (Для pedalboard) ===
31
- RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
32
- RUN rustup target add aarch64-linux-android
33
-
34
- # === ПОДГОТОВКА PYTHON ИНСТРУМЕНТОВ ===
35
- RUN pip install --upgrade pip && \
36
- pip install --no-cache-dir \
37
- Cython wheel setuptools poetry-core hatchling \
38
- hatch-fancy-pypi-readme hatch-vcs flit-core \
39
- expandvars maturin typing-extensions meson-python ninja
40
-
41
- WORKDIR ${WORK_DIR}
42
-
43
- # === УСТАНОВКА NDK ===
44
- RUN wget -q https://dl.google.com/android/repository/android-ndk-${NDK_VERSION}-linux.zip && \
45
- unzip -q android-ndk-${NDK_VERSION}-linux.zip && \
46
- mv android-ndk-${NDK_VERSION} ${NDK_HOME} && \
47
- rm android-ndk-${NDK_VERSION}-linux.zip
48
-
49
- ENV TOOLCHAIN=${NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64
50
- ENV PATH=${TOOLCHAIN}/bin:$PATH
51
- ENV TARGET=${ANDROID_ARCH}-linux-android${ANDROID_API}
52
- ENV CC="${TOOLCHAIN}/bin/${TARGET}-clang"
53
- ENV CXX="${TOOLCHAIN}/bin/${TARGET}-clang++"
54
- ENV AR="${TOOLCHAIN}/bin/llvm-ar"
55
- ENV NM="${TOOLCHAIN}/bin/llvm-nm"
56
- ENV LD="${TOOLCHAIN}/bin/ld"
57
- ENV RANLIB="${TOOLCHAIN}/bin/llvm-ranlib"
58
- ENV STRIP="${TOOLCHAIN}/bin/llvm-strip"
59
- ENV READELF="${TOOLCHAIN}/bin/llvm-readelf"
60
-
61
- ENV CFLAGS="-target ${TARGET} -fPIC -D__ANDROID__"
62
- ENV CXXFLAGS="-target ${TARGET} -fPIC -D__ANDROID__"
63
- ENV LDFLAGS="-target ${TARGET} -fPIC"
64
-
65
- # === СБОРКА OPENSSL (Для зависимостей pedalboard/rust) ===
66
- WORKDIR ${WORK_DIR}
67
- RUN wget -q https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz && \
68
- tar -xf openssl-${OPENSSL_VERSION}.tar.gz
69
-
70
- WORKDIR ${WORK_DIR}/openssl-${OPENSSL_VERSION}
71
-
72
- RUN ./Configure android-arm64 \
73
- -D__ANDROID_API__=${ANDROID_API} \
74
- --prefix=${WORK_DIR}/openssl-install \
75
- --openssldir=${WORK_DIR}/openssl-install \
76
- no-shared no-tests
77
-
78
- RUN make -j$(nproc) && make install_sw
79
-
80
- ENV OPENSSL_DIR=${WORK_DIR}/openssl-install
81
- ENV OPENSSL_LIB_DIR=${OPENSSL_DIR}/lib64
82
- ENV OPENSSL_INCLUDE_DIR=${OPENSSL_DIR}/include
83
- ENV OPENSSL_STATIC=1
84
-
85
- # === СБОРКА PYTHON (HOST) ДЛЯ ЗАГОЛОВКОВ ===
86
- WORKDIR ${WORK_DIR}
87
- RUN wget -q https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tgz && \
88
- tar -xf Python-${PYTHON_VERSION}.tgz
89
-
90
- WORKDIR ${WORK_DIR}/Python-${PYTHON_VERSION}
91
-
92
- # Фейковые настройки конфигурации для кросс-компиляции
93
- RUN echo "ac_cv_file__dev_ptmx=yes" > config.site && \
94
- echo "ac_cv_file__dev_ptc=no" >> config.site && \
95
- echo "ac_cv_func_wcsftime=no" >> config.site && \
96
- echo "ac_cv_func_gethostbyname_r=no" >> config.site && \
97
- echo "ac_cv_func_sendfile=no" >> config.site && \
98
- echo "ac_cv_func_broken_mbstowcs=no" >> config.site && \
99
- echo "ac_cv_func_wcscoll=no" >> config.site
100
-
101
- RUN CONFIG_SITE=config.site ./configure \
102
- CFLAGS="${CFLAGS}" \
103
- LDFLAGS="${LDFLAGS}" \
104
  --host=aarch64-linux-android \
105
  --build=x86_64-linux-gnu \
106
- --prefix=${WORK_DIR}/python-install \
107
- --disable-ipv6 \
108
  --enable-shared \
109
- --without-ensurepip \
110
- --with-build-python=/usr/local/bin/python3 \
111
- --disable-test-modules \
112
- --without-doc-strings \
113
- --with-system-ffi=no \
114
- --without-decimal \
115
- --without-ctypes
116
-
117
- RUN make -j$(nproc) libpython3.11.so || true
118
- RUN make install -i
119
-
120
- RUN mkdir -p ${WORK_DIR}/python-install/lib/python3.11
121
-
122
- # Хак для sysconfigdata, чтобы setuptools думал, что мы на arm64
123
- RUN find ${WORK_DIR}/Python-${PYTHON_VERSION} -name "_sysconfigdata*.py" -not -name "*x86_64*" \
124
- -exec cp {} ${WORK_DIR}/python-install/lib/python3.11/_sysconfigdata__linux_aarch64-linux-android.py \;
125
-
126
- RUN cp ${WORK_DIR}/python-install/lib/python3.11/_sysconfigdata__linux_aarch64-linux-android.py \
127
- /usr/local/lib/python3.11/_sysconfigdata__linux_aarch64-linux-android.py
128
-
129
- WORKDIR ${OUTPUT_DIR}
130
-
131
- # === НАСТРОЙКИ RUST ДЛЯ КРОСС-КОМПИЛЯЦИИ ===
132
- ENV CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="${CC}"
133
- 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}"
134
-
135
- # === СКРИПТ СБОРКИ ===
136
- RUN echo "#!/bin/bash" > build.sh && \
137
- echo "set -e" >> build.sh && \
138
- echo "export PYTHON_ANDROID_HOME=${WORK_DIR}/python-install" >> build.sh && \
139
- echo "export CFLAGS=\"${CFLAGS} -I\${PYTHON_ANDROID_HOME}/include/python3.11 -I${OPENSSL_INCLUDE_DIR}\"" >> build.sh && \
140
- echo "export LDFLAGS=\"${LDFLAGS} -L\${PYTHON_ANDROID_HOME}/lib -L${OPENSSL_LIB_DIR}\"" >> build.sh && \
141
- echo "export LDSHARED=\"${CC} -shared\"" >> build.sh && \
142
- echo "export _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata__linux_aarch64-linux-android" >> build.sh && \
143
- echo "export _PYTHON_HOST_PLATFORM=linux-aarch64" >> build.sh && \
144
- # Переменные для PyO3 (Pedalboard)
145
- echo "export PYO3_CROSS_LIB_DIR=${WORK_DIR}/python-install/lib" >> build.sh && \
146
- echo "export PYO3_CROSS_INCLUDE_DIR=${WORK_DIR}/python-install/include/python3.11" >> build.sh && \
147
- echo "export PYO3_CROSS_PYTHON_VERSION=3.11" >> build.sh && \
148
- echo "export CARGO_BUILD_TARGET=aarch64-linux-android" >> build.sh && \
149
- echo "export PYO3_NO_PYTHON_VERSION_CHECK=1" >> build.sh && \
150
- # Переменные для OpenSSL crate
151
- echo "export AARCH64_LINUX_ANDROID_OPENSSL_DIR=${OPENSSL_DIR}" >> build.sh && \
152
- echo "export AARCH64_LINUX_ANDROID_OPENSSL_LIB_DIR=${OPENSSL_LIB_DIR}" >> build.sh && \
153
- echo "export AARCH64_LINUX_ANDROID_OPENSSL_INCLUDE_DIR=${OPENSSL_INCLUDE_DIR}" >> build.sh && \
154
- echo "export OPENSSL_STATIC=1" >> build.sh && \
155
- # === СПЕЦИФИКА NUMPY ===
156
- # Отключаем поиск внешних библиотек BLAS/LAPACK, чтобы избежать ошибок линковки.
157
- # Numpy соберется с упрощенной линейной алгеброй.
158
- echo "export NPY_BLAS_ORDER=''" >> build.sh && \
159
- echo "export NPY_LAPACK_ORDER=''" >> build.sh && \
160
- echo "export NPY_DISABLE_SVML=1" >> build.sh && \
161
- echo "" >> build.sh && \
162
- echo "echo 'Starting Build for Numpy and Pedalboard...'" >> build.sh && \
163
- # Сборка. Используем --no-deps, чтобы собирать колеса по одному (или вместе, но контролируемо)
164
- echo "pip wheel numpy pedalboard --wheel-dir=${OUTPUT_DIR} --no-binary=:all: --no-build-isolation -v" >> build.sh && \
165
- chmod +x build.sh
166
-
167
- RUN ./build.sh
168
-
169
- # === POST-PROCESSING (PATCHELF) ===
170
- # Патчим зависимость от libpython3.11.so.1.0 -> libpython3.11.so
171
- RUN echo "Patching wheels..." && \
172
- for whl in *.whl; do \
173
- echo "Processing $whl..."; \
174
- mkdir -p tmp_wheel; \
175
- unzip -q "$whl" -d tmp_wheel; \
176
- find tmp_wheel -name "*.so" | while read so_file; do \
177
- if patchelf --print-needed "$so_file" | grep -q "libpython3.11.so.1.0"; then \
178
- echo " -> Patching $so_file"; \
179
- patchelf --replace-needed "libpython3.11.so.1.0" "libpython3.11.so" "$so_file"; \
180
- fi; \
181
- done; \
182
- cd tmp_wheel; \
183
- zip -r -q "../$whl" .; \
184
- cd ..; \
185
- rm -rf tmp_wheel; \
186
- done
187
-
188
- # === ПЕРЕИМЕНОВАНИЕ В ANDROID TAG ===
189
- RUN for f in *.whl; do \
190
- if [ -f "$f" ]; then \
191
- new_name=$(echo "$f" | sed 's/linux_aarch64/android_24_arm64_v8a/g'); \
192
- if [ "$f" != "$new_name" ]; then \
193
- mv "$f" "$new_name"; \
194
- fi \
195
- fi \
196
- done
197
-
198
- # === ГЕНЕРАЦИЯ ИНДЕКСА ===
199
- RUN echo "<html><head><title>Android Wheels</title></head><body>" > index.html && \
200
- echo "<h1>Numpy & Pedalboard Wheels (API 24, ARM64)</h1><ul>" >> index.html && \
201
- find . -name "*.whl" -printf "<li><a href=\"%P\">%P</a></li>\n" | sort >> index.html && \
202
- echo "</ul></body></html>" >> index.html
203
-
204
- EXPOSE 7860
205
- CMD ["python3", "-m", "http.server", "7860"]
 
1
+ FROM ubuntu:22.04
2
 
3
+ # 1. [...](asc_slot://start-slot-5)Установка системных зависимостей
4
+ ENV DEBIAN_FRONTEND=noninteractive
5
  RUN apt-get update && apt-get install -y \
6
+ wget \
7
+ unzip \
8
+ build-essential \
9
+ libffi-dev \
10
+ libssl-dev \
11
+ git \
12
+ pkg-config \
13
+ python3 \
14
+ python3-pip \
15
+ python3-dev \
16
  && rm -rf /var/lib/apt/lists/*
17
 
18
+ # 2. Настройка переменных окружения для Android NDK и Python
19
+ ENV ANDROID_NDK_VERSION=r25c
20
+ ENV ANDROID_API=30
21
+ ENV ANDROID_ARCH=arm64
22
+ ENV ANDROID_ABI=arm64-v8a
23
+ ENV PY_VERSION=3.11.9
24
+ ENV NDK_ROOT=/opt/android-ndk
25
+ ENV PATH=$NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH
26
+
27
+ # 3. [...](asc_slot://start-slot-7)Скачивание и распаковка Android NDK
28
+ WORKDIR /opt
29
+ RUN wget -q https://dl.google.com/android/repository/android-ndk-${ANDROID_NDK_VERSION}-linux.zip && \
30
+ unzip -q android-ndk-${ANDROID_NDK_VERSION}-linux.zip && \
31
+ mv android-ndk-${ANDROID_NDK_VERSION} android-ndk && \
32
+ rm android-ndk-${ANDROID_NDK_VERSION}-linux.zip
33
+
34
+ # 4. Скачивание исходников Python 3.11 (нужны для заголовков pyconfig.h под Android)
35
+ WORKDIR /opt/python-src
36
+ RUN wget -q https://www.python.org/ftp/python/${PY_VERSION}/Python-${PY_VERSION}.tgz && \
37
+ tar -xzf Python-${PY_VERSION}.tgz && \
38
+ mv Python-${PY_VERSION} python3-android
39
+
40
+ # 5. [...](asc_slot://start-slot-9)Настройка компиляторов для Cross-Compilation
41
+ # [...](asc_slot://start-slot-11)Мы создаем скрипт-обертку, чтобы "обмануть" configure питона и сгенерировать правильный pyconfig.h
42
+ WORKDIR /opt/python-src/python3-android
43
+
44
+ # Переменные для компиляции под Android API 30
45
+ ENV CC="aarch64-linux-android${ANDROID_API}-clang"
46
+ ENV CXX="aarch64-linux-android${ANDROID_API}-clang++"
47
+ ENV AR="llvm-ar"
48
+ ENV LD="ld.lld"
49
+ ENV READELF="llvm-readelf"
50
+ ENV RANLIB="llvm-ranlib"
51
+ ENV STRIP="llvm-strip"
52
+
53
+ # [...](asc_slot://start-slot-13)Флаги компиляции
54
+ ENV CFLAGS="-Os -fPIC -DANDROID -Wno-unused-result -Wno-unused-value -Wno-strict-aliasing"
55
+ ENV LDFLAGS="-L$NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/${ANDROID_API}"
56
+
57
+ # Конфигурируем Python (только чтобы создать Makefile и pyconfig.h)
58
+ # --build=x86_64-linux-gnu (где собираем)
59
+ # --host=aarch64-linux-android (для кого собираем)
60
+ # --disable-ipv6 (часто ломает сборку на андроиде без патчей)
61
+ RUN ./configure \
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  --host=aarch64-linux-android \
63
  --build=x86_64-linux-gnu \
 
 
64
  --enable-shared \
65
+ --disable-ipv6 \
66
+ ac_cv_file__dev_ptmx=no \
67
+ ac_cv_file__dev_ptc=no
68
+
69
+ # Нам не нужно компилировать весь Python, достаточно заголовков.
70
+ # Но pycryptodome нужен 'pyconfig.h', который создается после configure.
71
+
72
+ # 6. Сборка PyCryptodome
73
+ WORKDIR /build
74
+ RUN pip3 install build wheel
75
+
76
+ # [...](asc_slot://start-slot-15)Создаем скрипт сборки
77
+ RUN echo '#!/bin/bash' > build_wheel.sh && \
78
+ echo 'export CC="aarch64-linux-android'${ANDROID_API}'-clang"' >> build_wheel.sh && \
79
+ echo 'export LDSHARED="aarch64-linux-android'${ANDROID_API}'-clang -shared"' >> build_wheel.sh && \
80
+ echo 'export CFLAGS="-I/opt/python-src/python3-android -I/opt/python-src/python3-android/Include -DANDROID"' >> build_wheel.sh && \
81
+ # [...](asc_slot://start-slot-17)PyCryptodome специфичные флаги, чтобы он не пытался искать libgmp и использовал встроенные реализации
82
+ echo 'export LDFLAGS="-L/opt/python-src/python3-android"' >> build_wheel.sh && \
83
+ # [...](asc_slot://start-slot-19)Принудительно задаем платформу для имени файла
84
+ echo 'pip3 wheel pycryptodome --no-binary :all: --no-deps -w dist/ --build-option "--plat-name=android_21-30_arm64_v8a"' >> build_wheel.sh
85
+
86
+ RUN chmod +x build_wheel.sh
87
+
88
+ # Запускаем сборку
89
+ RUN ./build_wheel.sh
90
+
91
+ # 7. Финальная стадия: переименование (если pip не справился с точным форматом) и подготовка выдачи
92
+ # Pip может добавить лишние теги, поэтому мы жестко переименуем под ваш запрос.RUN cd dist && \
93
+ FIND_NAME=$(ls pycryptodome-*.whl | head -n 1) && \
94
+ # [...](asc_slot://start-slot-23)Разбираем имя: pycryptodome-3.19.0-cp311-cp311-linux_x86_64.whl -> pycryptodome-X.Y.Z-cp311-cp311-android_21-30_arm64_v8a.whl
95
+ # Но вы просили конкретный суффикс.
96
+ [...](asc_slot://start-slot-25)NEW_NAME=$(echo $FIND_NAME | sed -E 's/linux_x86_64|any|android_.*\.whl/android_21-30_arm64_v8a.whl/') && \
97
+ # [...](asc_slot://start-slot-27)Если sed не сработал идеально, форсируем:
98
+ VERSION=$(pip3 show pycryptodome | grep Version | awk '{print $2}') && \
99
+ FINAL_NAME="pycryptodome-${VERSION}-cp311-cp311-android_21-30_arm64_v8a.whl" && \
100
+ mv "$FIND_NAME" "/output/$FINAL_NAME" || mv "$FIND_NAME" "/output/pycryptodome-custom-android.whl"
101
+
102
+ # Создаем папку output для монтирования или скачивания
103
+ WORKDIR /output
104
+ # Копируем результат туда (на случай если предыдущий шаг был внутри слоя)
105
+ RUN cp /build/dist/*.whl . || true
106
+
107
+ # Чтобы контейнер не падал сразу, а дал забрать файл
108
+ CMD ["tail", "-f", "/dev/null"]