|
| 1 | +# Dockerfile with: |
| 2 | +# - Android build environment |
| 3 | +# - python-for-android dependencies |
| 4 | +# |
| 5 | +# Build with: |
| 6 | +# docker build --tag=p4a --file Dockerfile.py3 . |
| 7 | +# |
| 8 | +# Run with: |
| 9 | +# docker run -it --rm p4a /bin/sh -c '. venv/bin/activate && p4a apk --help' |
| 10 | +# |
| 11 | +# Or for interactive shell: |
| 12 | +# docker run -it --rm p4a |
| 13 | +# |
| 14 | +# Note: |
| 15 | +# Use 'docker run' without '--rm' flag for keeping the container and use |
| 16 | +# 'docker commit <container hash> <new image>' to extend the original image |
| 17 | + |
| 18 | +FROM ubuntu:18.04 |
| 19 | + |
| 20 | +ENV ANDROID_HOME="/opt/android" |
| 21 | + |
| 22 | +# configure locale |
| 23 | +RUN apt update -qq > /dev/null && apt install -qq --yes --no-install-recommends \ |
| 24 | + locales && \ |
| 25 | + locale-gen en_US.UTF-8 |
| 26 | +ENV LANG="en_US.UTF-8" \ |
| 27 | + LANGUAGE="en_US.UTF-8" \ |
| 28 | + LC_ALL="en_US.UTF-8" |
| 29 | + |
| 30 | + RUN apt -y update -qq \ |
| 31 | + && apt -y install -qq --no-install-recommends curl unzip ca-certificates \ |
| 32 | + && apt -y autoremove |
| 33 | + |
| 34 | +RUN apt-get update && apt-get install --no-install-recommends --yes \ |
| 35 | + autoconf \ |
| 36 | + automake \ |
| 37 | + build-essential \ |
| 38 | + ca-certificates \ |
| 39 | + cmake \ |
| 40 | + dh-systemd \ |
| 41 | + fakeroot \ |
| 42 | + git \ |
| 43 | + libswscale-dev \ |
| 44 | + libopenexr-dev \ |
| 45 | + lintian \ |
| 46 | + openjdk-8-jdk \ |
| 47 | + software-properties-common \ |
| 48 | + unzip \ |
| 49 | + yasm \ |
| 50 | + wget \ |
| 51 | + && apt-get clean && rm -rf /var/tmp/* |
| 52 | + |
| 53 | +# retry helper script, refs: |
| 54 | +# https://github.com/kivy/python-for-android/issues/1306 |
| 55 | +ENV RETRY="retry -t 3 --" |
| 56 | +RUN curl https://raw.githubusercontent.com/kadwanev/retry/1.0.1/retry \ |
| 57 | + --output /usr/local/bin/retry && chmod +x /usr/local/bin/retry |
| 58 | + |
| 59 | +ENV ANDROID_NDK_HOME="${ANDROID_HOME}/android-ndk" |
| 60 | +ENV ANDROID_NDK_VERSION="17c" |
| 61 | +ENV ANDROID_NDK_HOME_V="${ANDROID_NDK_HOME}-r${ANDROID_NDK_VERSION}" |
| 62 | + |
| 63 | +# get the latest version from https://developer.android.com/ndk/downloads/index.html |
| 64 | +ENV ANDROID_NDK_ARCHIVE="android-ndk-r${ANDROID_NDK_VERSION}-linux-x86_64.zip" |
| 65 | +ENV ANDROID_NDK_DL_URL="https://dl.google.com/android/repository/${ANDROID_NDK_ARCHIVE}" |
| 66 | + |
| 67 | +# download and install Android NDK |
| 68 | +RUN ${RETRY} curl --location --progress-bar --insecure \ |
| 69 | + "${ANDROID_NDK_DL_URL}" \ |
| 70 | + --output "${ANDROID_NDK_ARCHIVE}" \ |
| 71 | + && mkdir --parents "${ANDROID_NDK_HOME_V}" \ |
| 72 | + && unzip -q "${ANDROID_NDK_ARCHIVE}" -d "${ANDROID_HOME}" \ |
| 73 | + && ln -sfn "${ANDROID_NDK_HOME_V}" "${ANDROID_NDK_HOME}" \ |
| 74 | + && rm -rf "${ANDROID_NDK_ARCHIVE}" |
| 75 | + |
| 76 | + |
| 77 | +ENV ANDROID_SDK_HOME="${ANDROID_HOME}/android-sdk" |
| 78 | + |
| 79 | +# get the latest version from https://developer.android.com/studio/index.html |
| 80 | +ENV ANDROID_SDK_TOOLS_VERSION="3859397" |
| 81 | +ENV ANDROID_SDK_BUILD_TOOLS_VERSION="26.0.2" |
| 82 | +ENV ANDROID_SDK_TOOLS_ARCHIVE="sdk-tools-linux-${ANDROID_SDK_TOOLS_VERSION}.zip" |
| 83 | +ENV ANDROID_SDK_TOOLS_DL_URL="https://dl.google.com/android/repository/${ANDROID_SDK_TOOLS_ARCHIVE}" |
| 84 | + |
| 85 | +# download and install Android SDK |
| 86 | +RUN ${RETRY} curl --location --progress-bar --insecure \ |
| 87 | + "${ANDROID_SDK_TOOLS_DL_URL}" \ |
| 88 | + --output "${ANDROID_SDK_TOOLS_ARCHIVE}" \ |
| 89 | + && mkdir --parents "${ANDROID_SDK_HOME}" \ |
| 90 | + && unzip -q "${ANDROID_SDK_TOOLS_ARCHIVE}" -d "${ANDROID_SDK_HOME}" \ |
| 91 | + && rm -rf "${ANDROID_SDK_TOOLS_ARCHIVE}" |
| 92 | + |
| 93 | +# update Android SDK, install Android API, Build Tools... |
| 94 | +RUN mkdir --parents "${ANDROID_SDK_HOME}/.android/" \ |
| 95 | + && echo '### User Sources for Android SDK Manager' \ |
| 96 | + > "${ANDROID_SDK_HOME}/.android/repositories.cfg" |
| 97 | + |
| 98 | +# accept Android licenses (JDK necessary!) |
| 99 | +RUN ${RETRY} apt -y install -qq --no-install-recommends openjdk-8-jdk \ |
| 100 | + && apt -y autoremove |
| 101 | +RUN yes | "${ANDROID_SDK_HOME}/tools/bin/sdkmanager" "build-tools;${ANDROID_SDK_BUILD_TOOLS_VERSION}" > /dev/null |
| 102 | + |
| 103 | +# download platforms, API, build tools |
| 104 | +RUN "${ANDROID_SDK_HOME}/tools/bin/sdkmanager" "platforms;android-19" && \ |
| 105 | + "${ANDROID_SDK_HOME}/tools/bin/sdkmanager" "platforms;android-27" && \ |
| 106 | + "${ANDROID_SDK_HOME}/tools/bin/sdkmanager" "build-tools;${ANDROID_SDK_BUILD_TOOLS_VERSION}" && \ |
| 107 | + chmod +x "${ANDROID_SDK_HOME}/tools/bin/avdmanager" |
| 108 | + |
| 109 | +ENV NDK_ROOT ${ANDROID_NDK_HOME} |
| 110 | +ENV ANDROID_NATIVE_API_LEVEL ${ANDROIDAPI} |
| 111 | +ENV ANDROID_ABI "armeabi-v7a" |
| 112 | +ENV TARGET_ANDROID_ABI $ANDROID_ABI |
| 113 | + |
| 114 | +ENV TOOLCHAIN arm-linux-androideabi-4.9 |
| 115 | +ENV TOOLCHAIN_DIR ${ANDROID_NDK_HOME}/toolchains/${TOOLCHAIN} |
| 116 | + |
| 117 | +# ENV CMAKE_TOOLCHAIN_FILE ${PROJECT_DIR}/android-cmake/android.toolchain.cmake |
| 118 | +# ENV CMAKE_TOOLCHAIN_FILE /opt/tools/cmake/3.6.4111459/android.toolchain.cmake |
| 119 | +ENV CMAKE_TOOLCHAIN_FILE ${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake |
| 120 | + |
| 121 | + |
| 122 | +# Host libraries |
| 123 | +ENV PROJECT_DIR /opt/src |
| 124 | +ENV INSTALL_DIR /opt/install |
| 125 | +ENV N_JOBS ${N_JOBS:-4} |
| 126 | +ENV OS linux |
| 127 | +ENV ARCH x86_64 |
| 128 | + |
| 129 | +# golang |
| 130 | +ENV GOLANG_VERSION 1.12.4 |
| 131 | +RUN curl -Lo /tmp/go.tar.gz \ |
| 132 | + https://golang.org/dl/go${GOLANG_VERSION}.linux-amd64.tar.gz \ |
| 133 | + && tar -C /usr/local -xzf /tmp/go.tar.gz \ |
| 134 | + && rm /tmp/go.tar.gz |
| 135 | +ENV PATH "/usr/local/go/bin:${PATH}" |
| 136 | +RUN go version |
| 137 | + |
| 138 | + |
| 139 | +# gFlags |
| 140 | +ENV GFLAGS_VERSION v2.2.1 |
| 141 | +ENV BUILD_DIR /opt/build/gflags |
| 142 | +RUN mkdir -p ${PROJECT_DIR}/gflags \ |
| 143 | + && curl -Lo /tmp/gflags.tar.gz \ |
| 144 | + https://github.com/gflags/gflags/archive/${GFLAGS_VERSION}.tar.gz \ |
| 145 | + && tar -xzvf /tmp/gflags.tar.gz -C ${PROJECT_DIR}/gflags --strip-components 1 \ |
| 146 | + && rm /tmp/gflags.tar.gz \ |
| 147 | + && mkdir -p "${BUILD_DIR}" && cd "${BUILD_DIR}" \ |
| 148 | + && cmake -DCMAKE_TOOLCHAIN_FILE="${CMAKE_TOOLCHAIN_FILE}" \ |
| 149 | + -DANDROID_NDK="${NDK_ROOT}" \ |
| 150 | + -DCMAKE_BUILD_TYPE=Release \ |
| 151 | + -DANDROID_ABI="${ANDROID_ABI}" \ |
| 152 | + -DANDROID_NATIVE_API_LEVEL=21 \ |
| 153 | + -DANDROID_STL=c++_static \ |
| 154 | + -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \ |
| 155 | + -DCMAKE_FIND_ROOT_PATH="${INSTALL_DIR}" \ |
| 156 | + "${PROJECT_DIR}/gflags" \ |
| 157 | + && cmake --build . --target install/strip -- -j"${N_JOBS}" \ |
| 158 | + && rm -rf "${BUILD_DIR}" |
| 159 | + |
| 160 | + |
| 161 | +# gLog |
| 162 | +ENV GLOG_VERSION v0.3.5 |
| 163 | +ENV BUILD_DIR /opt/build/glog |
| 164 | +# COPY caffe-android-lib/glog ${PROJECT_DIR}/glog |
| 165 | +RUN mkdir -p ${PROJECT_DIR}/glog \ |
| 166 | + && curl -Lo /tmp/glog.tar.gz \ |
| 167 | + https://github.com/google/glog/archive/${GLOG_VERSION}.tar.gz \ |
| 168 | + && tar -xzvf /tmp/glog.tar.gz -C ${PROJECT_DIR}/glog --strip-components 1 \ |
| 169 | + && rm /tmp/glog.tar.gz \ |
| 170 | + && mkdir -p "${BUILD_DIR}" && cd "${BUILD_DIR}" \ |
| 171 | + && cmake -DCMAKE_TOOLCHAIN_FILE="${CMAKE_TOOLCHAIN_FILE}" \ |
| 172 | + -DANDROID_NDK="${NDK_ROOT}" \ |
| 173 | + -DCMAKE_BUILD_TYPE=Release \ |
| 174 | + -DANDROID_ABI="${ANDROID_ABI}" \ |
| 175 | + -DANDROID_NATIVE_API_LEVEL=21 \ |
| 176 | + -DANDROID_STL=c++_static \ |
| 177 | + -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \ |
| 178 | + -DCMAKE_FIND_ROOT_PATH="${INSTALL_DIR}" \ |
| 179 | + -DBUILD_TESTING=OFF \ |
| 180 | + "${PROJECT_DIR}/glog" \ |
| 181 | + && cmake --build . --target install/strip -- -j"${N_JOBS}" \ |
| 182 | + && rm -rf "${BUILD_DIR}" |
| 183 | + |
| 184 | + |
| 185 | +# gRPC |
| 186 | +ENV GRPC_ROOT ${PROJECT_DIR}/grpc |
| 187 | +ENV GRPC_RELEASE_TAG v1.20.1 |
| 188 | +# ENV BUILD_DIR /opt/build/grpc |
| 189 | +RUN git clone -b ${GRPC_RELEASE_TAG} https://github.com/grpc/grpc ${GRPC_ROOT} \ |
| 190 | + && cd ${GRPC_ROOT} \ |
| 191 | + && git submodule update --init |
| 192 | + |
| 193 | +# Host Protobuf |
| 194 | +# This is needed because we will run "protoc" when building other dependencies. |
| 195 | +# The target "protoc" executable doesn't work because of the platform mismatch |
| 196 | +ENV BUILD_DIR /opt/build/protobuf_host |
| 197 | +RUN mkdir -p "${BUILD_DIR}" && cd "${BUILD_DIR}" \ |
| 198 | + && cmake \ |
| 199 | + -Dprotobuf_BUILD_TESTS=OFF \ |
| 200 | + ${PROJECT_DIR}/grpc/third_party/protobuf/cmake \ |
| 201 | + && cmake --build . --target install/strip -- -j"${N_JOBS}" \ |
| 202 | + && rm -rf "${BUILD_DIR}" |
| 203 | + |
| 204 | +# RUN apt-get install --yes zlib1g-dev libc-ares-dev libssl1.0-dev |
| 205 | + |
| 206 | +# GRPC HOST # |
| 207 | +ENV BUILD_DIR /opt/build/grpc-host |
| 208 | +RUN mkdir -p ${BUILD_DIR} && cd ${BUILD_DIR} \ |
| 209 | + && cmake \ |
| 210 | + -DCMAKE_BUILD_TYPE=Release \ |
| 211 | + -DProtobuf_PROTOC_EXECUTABLE=/usr/local/bin/protoc \ |
| 212 | + -DgRPC_INSTALL=ON \ |
| 213 | + -DgRPC_BUILD_TESTS=OFF \ |
| 214 | + ${GRPC_ROOT} \ |
| 215 | + && cmake --build . --target install/strip -- -j"${N_JOBS}" |
| 216 | + # We don't remove this because some executables are not installed (to fix) |
| 217 | + # && rm -rf "${BUILD_DIR}" |
| 218 | + |
| 219 | +# Android ZLib |
| 220 | +# To understand why submodules zlib, cares and protobuf are being built and |
| 221 | +# removed from grpc tree check: https://github.com/grpc/grpc/issues/13841 |
| 222 | +ENV BUILD_DIR /opt/build/zlib |
| 223 | +RUN mkdir -p "${BUILD_DIR}" && cd "${BUILD_DIR}" \ |
| 224 | + && cmake -DCMAKE_TOOLCHAIN_FILE="${CMAKE_TOOLCHAIN_FILE}" \ |
| 225 | + -DANDROID_NDK="${NDK_ROOT}" \ |
| 226 | + -DCMAKE_BUILD_TYPE=Release \ |
| 227 | + -DANDROID_ABI="${ANDROID_ABI}" \ |
| 228 | + -DANDROID_NATIVE_API_LEVEL=21 \ |
| 229 | + -DANDROID_STL=c++_static \ |
| 230 | + -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \ |
| 231 | + -DCMAKE_FIND_ROOT_PATH="${INSTALL_DIR}" \ |
| 232 | + ${PROJECT_DIR}/grpc/third_party/zlib \ |
| 233 | + && cmake --build . --target install/strip -- -j"${N_JOBS}" \ |
| 234 | + && rm -rf "${BUILD_DIR}" \ |
| 235 | + # Wipe out to prevent influencing the grpc build |
| 236 | + && rm -rf ${PROJECT_DIR}/grpc/third_party/zlib |
| 237 | + |
| 238 | +# Android c-ares |
| 239 | +ENV BUILD_DIR /opt/build/cares |
| 240 | +RUN mkdir -p "${BUILD_DIR}" && cd "${BUILD_DIR}" \ |
| 241 | + && cmake -DCMAKE_TOOLCHAIN_FILE="${CMAKE_TOOLCHAIN_FILE}" \ |
| 242 | + -DANDROID_NDK="${NDK_ROOT}" \ |
| 243 | + -DCMAKE_BUILD_TYPE=Release \ |
| 244 | + -DANDROID_ABI="${ANDROID_ABI}" \ |
| 245 | + -DANDROID_NATIVE_API_LEVEL=21 \ |
| 246 | + -DANDROID_STL=c++_static \ |
| 247 | + -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \ |
| 248 | + -DCMAKE_FIND_ROOT_PATH="${INSTALL_DIR}" \ |
| 249 | + ${PROJECT_DIR}/grpc/third_party/cares/cares \ |
| 250 | + && cmake --build . --target install/strip -- -j"${N_JOBS}" \ |
| 251 | + && rm -rf "${BUILD_DIR}" \ |
| 252 | + # Wipe out to prevent influencing the grpc build |
| 253 | + && rm -rf ${PROJECT_DIR}/grpc/third_party/cares |
| 254 | + |
| 255 | +ENV OPENSSL_ROOT ${PROJECT_DIR}/openssl |
| 256 | +RUN mkdir -p ${OPENSSL_ROOT} \ |
| 257 | + && curl -Lo /tmp/openssl.tar.gz \ |
| 258 | + https://github.com/openssl/openssl/archive/OpenSSL_1_1_1b.tar.gz \ |
| 259 | + && tar -xzvf /tmp/openssl.tar.gz -C ${OPENSSL_ROOT} --strip-components 1 \ |
| 260 | + && cd ${OPENSSL_ROOT} \ |
| 261 | + && PATH="${TOOLCHAIN_DIR}/prebuilt/linux-x86_64/bin/:${PATH}" ./Configure android-arm -D__ANDROID_API__=21 \ |
| 262 | + && PATH="${TOOLCHAIN_DIR}/prebuilt/linux-x86_64/bin/:${PATH}" make install |
| 263 | + |
| 264 | +# Android Protobuf |
| 265 | +ENV BUILD_DIR /opt/build/protobuf |
| 266 | +RUN mkdir -p "${BUILD_DIR}" && cd "${BUILD_DIR}" \ |
| 267 | + && cmake -DCMAKE_TOOLCHAIN_FILE="${CMAKE_TOOLCHAIN_FILE}" \ |
| 268 | + -DANDROID_NDK="${NDK_ROOT}" \ |
| 269 | + -DCMAKE_BUILD_TYPE=Release \ |
| 270 | + -DANDROID_ABI="${ANDROID_ABI}" \ |
| 271 | + -DANDROID_NATIVE_API_LEVEL=21 \ |
| 272 | + -DCMAKE_CXX_STANDARD=11 \ |
| 273 | + -DANDROID_STL=c++_static \ |
| 274 | + -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \ |
| 275 | + -DCMAKE_FIND_ROOT_PATH="${INSTALL_DIR}" \ |
| 276 | + -Dprotobuf_BUILD_TESTS=OFF \ |
| 277 | + -DCMAKE_EXE_LINKER_FLAGS="-llog" \ |
| 278 | + #-Dprotobuf_BUILD_PROTOC_BINARIES=OFF \ |
| 279 | + ${PROJECT_DIR}/grpc/third_party/protobuf/cmake \ |
| 280 | + && cmake --build . --target install/strip -- -j"${N_JOBS}" \ |
| 281 | + && rm -rf "${BUILD_DIR}" \ |
| 282 | + # Wipe out to prevent influencing the grpc build |
| 283 | + && rm -rf ${PROJECT_DIR}/grpc/third_party/protobuf \ |
| 284 | + # bug: link symbolics missed for GRPC compiling |
| 285 | + && ln -sf /opt/android/android-ndk/platforms/android-21/arch-arm/usr/lib/libc.so /opt/android/android-ndk/platforms/android-21/arch-arm/usr/lib/libnsl.so \ |
| 286 | + && ln -sf /opt/android/android-ndk/platforms/android-21/arch-arm/usr/lib/libc.so /opt/android/android-ndk/platforms/android-21/arch-arm/usr/lib/librt.so |
| 287 | + |
| 288 | +# Python and user packages |
| 289 | + |
| 290 | +ENV USER="user" |
| 291 | +ENV HOME_DIR="/home/${USER}" |
| 292 | +ENV WORK_DIR="${HOME_DIR}" \ |
| 293 | + PATH="${HOME_DIR}/.local/bin:${PATH}" |
| 294 | + |
| 295 | +# install system dependencies |
| 296 | +RUN ${RETRY} apt -y install -qq --no-install-recommends \ |
| 297 | + python3 virtualenv python3-pip python3-venv \ |
| 298 | + wget lbzip2 patch sudo \ |
| 299 | + && apt -y autoremove |
| 300 | + |
| 301 | +# build dependencies |
| 302 | +# https://buildozer.readthedocs.io/en/latest/installation.html#android-on-ubuntu-16-04-64bit |
| 303 | +RUN dpkg --add-architecture i386 \ |
| 304 | + && ${RETRY} apt -y update -qq \ |
| 305 | + && ${RETRY} apt -y install -qq --no-install-recommends \ |
| 306 | + build-essential ccache git python3 python3-dev \ |
| 307 | + libncurses5:i386 libstdc++6:i386 libgtk2.0-0:i386 \ |
| 308 | + libpangox-1.0-0:i386 libpangoxft-1.0-0:i386 libidn11:i386 \ |
| 309 | + zip zlib1g-dev zlib1g:i386 \ |
| 310 | + && apt -y autoremove |
| 311 | + |
| 312 | +# specific recipes dependencies (e.g. libffi requires autoreconf binary) |
| 313 | +RUN ${RETRY} apt -y install -qq --no-install-recommends \ |
| 314 | + libffi-dev autoconf automake cmake gettext libltdl-dev libtool pkg-config \ |
| 315 | + && apt -y autoremove \ |
| 316 | + && apt -y clean |
| 317 | + |
| 318 | +# prepare non root env |
| 319 | +RUN useradd --create-home --shell /bin/bash ${USER} |
| 320 | + |
| 321 | +# with sudo access and no password |
| 322 | +RUN usermod -append --groups sudo ${USER} |
| 323 | +RUN echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers |
| 324 | + |
| 325 | + |
| 326 | +RUN pip3 install --upgrade cython==0.29.7 |
| 327 | + |
| 328 | +WORKDIR ${WORK_DIR} |
| 329 | +COPY --chown=user:user . ${WORK_DIR} |
| 330 | +RUN chown --recursive ${USER} ${ANDROID_SDK_HOME} |
| 331 | +USER ${USER} |
| 332 | + |
| 333 | +# install python-for-android from current branch |
| 334 | +RUN virtualenv --python=python3 venv \ |
| 335 | + && . venv/bin/activate \ |
| 336 | + && pip3 install -e . |
| 337 | + |
0 commit comments