1*da0073e9SAndroid Build Coastguard Worker#!/bin/bash 2*da0073e9SAndroid Build Coastguard Worker############################################################################## 3*da0073e9SAndroid Build Coastguard Worker# Example command to build the android target. 4*da0073e9SAndroid Build Coastguard Worker############################################################################## 5*da0073e9SAndroid Build Coastguard Worker# 6*da0073e9SAndroid Build Coastguard Worker# This script shows how one can build a Caffe2 binary for the Android platform 7*da0073e9SAndroid Build Coastguard Worker# using android-cmake. A few notes: 8*da0073e9SAndroid Build Coastguard Worker# 9*da0073e9SAndroid Build Coastguard Worker# (1) This build also does a host build for protobuf. You will need autoconf 10*da0073e9SAndroid Build Coastguard Worker# to carry out this. If autoconf is not possible, you will need to provide 11*da0073e9SAndroid Build Coastguard Worker# a pre-built protoc binary that is the same version as the protobuf 12*da0073e9SAndroid Build Coastguard Worker# version under third_party. 13*da0073e9SAndroid Build Coastguard Worker# If you are building on Mac, you might need to install autotool and 14*da0073e9SAndroid Build Coastguard Worker# libtool. The easiest way is via homebrew: 15*da0073e9SAndroid Build Coastguard Worker# brew install automake 16*da0073e9SAndroid Build Coastguard Worker# brew install libtool 17*da0073e9SAndroid Build Coastguard Worker# (2) You will need to have android ndk installed. The current script assumes 18*da0073e9SAndroid Build Coastguard Worker# that you set ANDROID_NDK to the location of ndk. 19*da0073e9SAndroid Build Coastguard Worker# (3) The toolchain and the build target platform can be specified with the 20*da0073e9SAndroid Build Coastguard Worker# cmake arguments below. For more details, check out android-cmake's doc. 21*da0073e9SAndroid Build Coastguard Worker 22*da0073e9SAndroid Build Coastguard Workerset -e 23*da0073e9SAndroid Build Coastguard Worker 24*da0073e9SAndroid Build Coastguard Worker# Android specific flags 25*da0073e9SAndroid Build Coastguard Workerif [ -z "$ANDROID_ABI" ]; then 26*da0073e9SAndroid Build Coastguard Worker ANDROID_ABI="armeabi-v7a with NEON" 27*da0073e9SAndroid Build Coastguard Workerfi 28*da0073e9SAndroid Build Coastguard WorkerANDROID_NATIVE_API_LEVEL="21" 29*da0073e9SAndroid Build Coastguard Workerecho "Build with ANDROID_ABI[$ANDROID_ABI], ANDROID_NATIVE_API_LEVEL[$ANDROID_NATIVE_API_LEVEL]" 30*da0073e9SAndroid Build Coastguard Worker 31*da0073e9SAndroid Build Coastguard WorkerCAFFE2_ROOT="$( cd "$(dirname "$0")"/.. ; pwd -P)" 32*da0073e9SAndroid Build Coastguard Workerif [ -z "$ANDROID_NDK" ]; then 33*da0073e9SAndroid Build Coastguard Worker echo "ANDROID_NDK not set; please set it to the Android NDK directory" 34*da0073e9SAndroid Build Coastguard Worker exit 1 35*da0073e9SAndroid Build Coastguard Workerfi 36*da0073e9SAndroid Build Coastguard Worker 37*da0073e9SAndroid Build Coastguard Workerif [ ! -d "$ANDROID_NDK" ]; then 38*da0073e9SAndroid Build Coastguard Worker echo "ANDROID_NDK not a directory; did you install it under $ANDROID_NDK?" 39*da0073e9SAndroid Build Coastguard Worker exit 1 40*da0073e9SAndroid Build Coastguard Workerfi 41*da0073e9SAndroid Build Coastguard Worker 42*da0073e9SAndroid Build Coastguard Workerif [ -z "$PYTHON" ]; then 43*da0073e9SAndroid Build Coastguard Worker PYTHON=python 44*da0073e9SAndroid Build Coastguard Worker PYTHON_VERSION_MAJOR=$($PYTHON -c 'import sys; print(sys.version_info[0])') 45*da0073e9SAndroid Build Coastguard Worker if [ "${PYTHON_VERSION_MAJOR}" -le 2 ]; then 46*da0073e9SAndroid Build Coastguard Worker echo "Default python executable is Python-2, trying to use python3 alias" 47*da0073e9SAndroid Build Coastguard Worker PYTHON=python3 48*da0073e9SAndroid Build Coastguard Worker fi 49*da0073e9SAndroid Build Coastguard Workerfi 50*da0073e9SAndroid Build Coastguard Worker 51*da0073e9SAndroid Build Coastguard WorkerANDROID_NDK_PROPERTIES="$ANDROID_NDK/source.properties" 52*da0073e9SAndroid Build Coastguard Worker[ -f "$ANDROID_NDK_PROPERTIES" ] && ANDROID_NDK_VERSION=$(sed -n 's/^Pkg.Revision[^=]*= *\([0-9]*\)\..*$/\1/p' "$ANDROID_NDK_PROPERTIES") 53*da0073e9SAndroid Build Coastguard Worker 54*da0073e9SAndroid Build Coastguard Workerecho "Bash: $(/bin/bash --version | head -1)" 55*da0073e9SAndroid Build Coastguard Workerecho "Python: $($PYTHON -c 'import sys; print(sys.version)')" 56*da0073e9SAndroid Build Coastguard Workerecho "Caffe2 path: $CAFFE2_ROOT" 57*da0073e9SAndroid Build Coastguard Workerecho "Using Android NDK at $ANDROID_NDK" 58*da0073e9SAndroid Build Coastguard Workerecho "Android NDK version: $ANDROID_NDK_VERSION" 59*da0073e9SAndroid Build Coastguard Worker 60*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS=() 61*da0073e9SAndroid Build Coastguard Worker 62*da0073e9SAndroid Build Coastguard Worker# Build PyTorch mobile 63*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS+=("-DCMAKE_PREFIX_PATH=$($PYTHON -c 'import sysconfig; print(sysconfig.get_path("purelib"))')") 64*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS+=("-DPython_EXECUTABLE=$($PYTHON -c 'import sys; print(sys.executable)')") 65*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS+=("-DBUILD_CUSTOM_PROTOBUF=OFF") 66*da0073e9SAndroid Build Coastguard Worker 67*da0073e9SAndroid Build Coastguard Worker# custom build with selected ops 68*da0073e9SAndroid Build Coastguard Workerif [ -n "${SELECTED_OP_LIST}" ]; then 69*da0073e9SAndroid Build Coastguard Worker SELECTED_OP_LIST="$(cd $(dirname $SELECTED_OP_LIST); pwd -P)/$(basename $SELECTED_OP_LIST)" 70*da0073e9SAndroid Build Coastguard Worker echo "Choose SELECTED_OP_LIST file: $SELECTED_OP_LIST" 71*da0073e9SAndroid Build Coastguard Worker if [ ! -r ${SELECTED_OP_LIST} ]; then 72*da0073e9SAndroid Build Coastguard Worker echo "Error: SELECTED_OP_LIST file ${SELECTED_OP_LIST} not found." 73*da0073e9SAndroid Build Coastguard Worker exit 1 74*da0073e9SAndroid Build Coastguard Worker fi 75*da0073e9SAndroid Build Coastguard Worker CMAKE_ARGS+=("-DSELECTED_OP_LIST=${SELECTED_OP_LIST}") 76*da0073e9SAndroid Build Coastguard Workerfi 77*da0073e9SAndroid Build Coastguard Worker 78*da0073e9SAndroid Build Coastguard Worker# If Ninja is installed, prefer it to Make 79*da0073e9SAndroid Build Coastguard Workerif [ -x "$(command -v ninja)" ]; then 80*da0073e9SAndroid Build Coastguard Worker CMAKE_ARGS+=("-GNinja") 81*da0073e9SAndroid Build Coastguard Workerfi 82*da0073e9SAndroid Build Coastguard Worker 83*da0073e9SAndroid Build Coastguard Worker# Use android-cmake to build Android project from CMake. 84*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS+=("-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake") 85*da0073e9SAndroid Build Coastguard Worker 86*da0073e9SAndroid Build Coastguard Workerif [ -z "$BUILD_MOBILE_BENCHMARK" ]; then 87*da0073e9SAndroid Build Coastguard Worker BUILD_MOBILE_BENCHMARK=0 88*da0073e9SAndroid Build Coastguard Workerfi 89*da0073e9SAndroid Build Coastguard Worker 90*da0073e9SAndroid Build Coastguard Workerif [ -z "$BUILD_MOBILE_TEST" ]; then 91*da0073e9SAndroid Build Coastguard Worker BUILD_MOBILE_TEST=0 92*da0073e9SAndroid Build Coastguard Workerfi 93*da0073e9SAndroid Build Coastguard Worker# Don't build artifacts we don't need 94*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS+=("-DBUILD_TEST=OFF") 95*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS+=("-DBUILD_BINARY=OFF") 96*da0073e9SAndroid Build Coastguard Worker 97*da0073e9SAndroid Build Coastguard Worker# If there exists env variable and it equals to 0, build full jit interpreter. 98*da0073e9SAndroid Build Coastguard Worker# Default behavior is to build lite interpreter 99*da0073e9SAndroid Build Coastguard Worker# cmd: BUILD_LITE_INTERPRETER=0 ./scripts/build_android.sh 100*da0073e9SAndroid Build Coastguard Workerif [ "${BUILD_LITE_INTERPRETER}" == 0 ]; then 101*da0073e9SAndroid Build Coastguard Worker CMAKE_ARGS+=("-DBUILD_LITE_INTERPRETER=OFF") 102*da0073e9SAndroid Build Coastguard Workerelse 103*da0073e9SAndroid Build Coastguard Worker CMAKE_ARGS+=("-DBUILD_LITE_INTERPRETER=ON") 104*da0073e9SAndroid Build Coastguard Workerfi 105*da0073e9SAndroid Build Coastguard Workerif [ "${TRACING_BASED}" == 1 ]; then 106*da0073e9SAndroid Build Coastguard Worker CMAKE_ARGS+=("-DTRACING_BASED=ON") 107*da0073e9SAndroid Build Coastguard Workerelse 108*da0073e9SAndroid Build Coastguard Worker CMAKE_ARGS+=("-DTRACING_BASED=OFF") 109*da0073e9SAndroid Build Coastguard Workerfi 110*da0073e9SAndroid Build Coastguard Workerif [ "${USE_LIGHTWEIGHT_DISPATCH}" == 1 ]; then 111*da0073e9SAndroid Build Coastguard Worker CMAKE_ARGS+=("-DUSE_LIGHTWEIGHT_DISPATCH=ON") 112*da0073e9SAndroid Build Coastguard Worker CMAKE_ARGS+=("-DSTATIC_DISPATCH_BACKEND=CPU") 113*da0073e9SAndroid Build Coastguard Workerelse 114*da0073e9SAndroid Build Coastguard Worker CMAKE_ARGS+=("-DUSE_LIGHTWEIGHT_DISPATCH=OFF") 115*da0073e9SAndroid Build Coastguard Workerfi 116*da0073e9SAndroid Build Coastguard Worker 117*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS+=("-DBUILD_MOBILE_BENCHMARK=$BUILD_MOBILE_BENCHMARK") 118*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS+=("-DBUILD_MOBILE_TEST=$BUILD_MOBILE_TEST") 119*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS+=("-DBUILD_PYTHON=OFF") 120*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS+=("-DBUILD_SHARED_LIBS=OFF") 121*da0073e9SAndroid Build Coastguard Workerif (( "${ANDROID_NDK_VERSION:-0}" < 18 )); then 122*da0073e9SAndroid Build Coastguard Worker CMAKE_ARGS+=("-DANDROID_TOOLCHAIN=gcc") 123*da0073e9SAndroid Build Coastguard Workerelse 124*da0073e9SAndroid Build Coastguard Worker CMAKE_ARGS+=("-DANDROID_TOOLCHAIN=clang") 125*da0073e9SAndroid Build Coastguard Workerfi 126*da0073e9SAndroid Build Coastguard Worker# Disable unused dependencies 127*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS+=("-DUSE_CUDA=OFF") 128*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS+=("-DUSE_ITT=OFF") 129*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS+=("-DUSE_GFLAGS=OFF") 130*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS+=("-DUSE_OPENCV=OFF") 131*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS+=("-DUSE_MPI=OFF") 132*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS+=("-DUSE_OPENMP=OFF") 133*da0073e9SAndroid Build Coastguard Worker# Only toggle if VERBOSE=1 134*da0073e9SAndroid Build Coastguard Workerif [ "${VERBOSE:-}" == '1' ]; then 135*da0073e9SAndroid Build Coastguard Worker CMAKE_ARGS+=("-DCMAKE_VERBOSE_MAKEFILE=1") 136*da0073e9SAndroid Build Coastguard Workerfi 137*da0073e9SAndroid Build Coastguard Worker 138*da0073e9SAndroid Build Coastguard Worker# Android specific flags 139*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS+=("-DANDROID_NDK=$ANDROID_NDK") 140*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS+=("-DANDROID_ABI=$ANDROID_ABI") 141*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS+=("-DANDROID_NATIVE_API_LEVEL=$ANDROID_NATIVE_API_LEVEL") 142*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS+=("-DANDROID_CPP_FEATURES=rtti exceptions") 143*da0073e9SAndroid Build Coastguard Workerif [ "${ANDROID_STL_SHARED:-}" == '1' ]; then 144*da0073e9SAndroid Build Coastguard Worker CMAKE_ARGS+=("-DANDROID_STL=c++_shared") 145*da0073e9SAndroid Build Coastguard Workerfi 146*da0073e9SAndroid Build Coastguard Workerif [ "${ANDROID_DEBUG_SYMBOLS:-}" == '1' ]; then 147*da0073e9SAndroid Build Coastguard Worker CMAKE_ARGS+=("-DANDROID_DEBUG_SYMBOLS=1") 148*da0073e9SAndroid Build Coastguard Workerfi 149*da0073e9SAndroid Build Coastguard Worker 150*da0073e9SAndroid Build Coastguard Workerif [ -n "${USE_VULKAN}" ]; then 151*da0073e9SAndroid Build Coastguard Worker CMAKE_ARGS+=("-DUSE_VULKAN=ON") 152*da0073e9SAndroid Build Coastguard Worker if [ -n "${USE_VULKAN_FP16_INFERENCE}" ]; then 153*da0073e9SAndroid Build Coastguard Worker CMAKE_ARGS+=("-DUSE_VULKAN_FP16_INFERENCE=ON") 154*da0073e9SAndroid Build Coastguard Worker fi 155*da0073e9SAndroid Build Coastguard Worker if [ -n "${USE_VULKAN_RELAXED_PRECISION}" ]; then 156*da0073e9SAndroid Build Coastguard Worker CMAKE_ARGS+=("-DUSE_VULKAN_RELAXED_PRECISION=ON") 157*da0073e9SAndroid Build Coastguard Worker fi 158*da0073e9SAndroid Build Coastguard Workerfi 159*da0073e9SAndroid Build Coastguard Worker 160*da0073e9SAndroid Build Coastguard Worker# Use-specified CMake arguments go last to allow overridding defaults 161*da0073e9SAndroid Build Coastguard WorkerCMAKE_ARGS+=($@) 162*da0073e9SAndroid Build Coastguard Worker 163*da0073e9SAndroid Build Coastguard Worker# Patch pocketfft (as Android does not have aligned_alloc even if compiled with c++17 164*da0073e9SAndroid Build Coastguard Workerif [ -f third_party/pocketfft/pocketfft_hdronly.h ]; then 165*da0073e9SAndroid Build Coastguard Worker sed -i -e "s/__cplusplus >= 201703L/0/" third_party/pocketfft/pocketfft_hdronly.h 166*da0073e9SAndroid Build Coastguard Workerfi 167*da0073e9SAndroid Build Coastguard Worker 168*da0073e9SAndroid Build Coastguard Worker# Now, actually build the Android target. 169*da0073e9SAndroid Build Coastguard WorkerBUILD_ROOT=${BUILD_ROOT:-"$CAFFE2_ROOT/build_android"} 170*da0073e9SAndroid Build Coastguard WorkerINSTALL_PREFIX=${BUILD_ROOT}/install 171*da0073e9SAndroid Build Coastguard Workermkdir -p $BUILD_ROOT 172*da0073e9SAndroid Build Coastguard Workercd $BUILD_ROOT 173*da0073e9SAndroid Build Coastguard Workercmake "$CAFFE2_ROOT" \ 174*da0073e9SAndroid Build Coastguard Worker -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX \ 175*da0073e9SAndroid Build Coastguard Worker -DCMAKE_BUILD_TYPE=Release \ 176*da0073e9SAndroid Build Coastguard Worker "${CMAKE_ARGS[@]}" 177*da0073e9SAndroid Build Coastguard Worker 178*da0073e9SAndroid Build Coastguard Worker# Cross-platform parallel build 179*da0073e9SAndroid Build Coastguard Workerif [ -z "$MAX_JOBS" ]; then 180*da0073e9SAndroid Build Coastguard Worker if [ "$(uname)" == 'Darwin' ]; then 181*da0073e9SAndroid Build Coastguard Worker MAX_JOBS=$(sysctl -n hw.ncpu) 182*da0073e9SAndroid Build Coastguard Worker else 183*da0073e9SAndroid Build Coastguard Worker MAX_JOBS=$(nproc) 184*da0073e9SAndroid Build Coastguard Worker fi 185*da0073e9SAndroid Build Coastguard Workerfi 186*da0073e9SAndroid Build Coastguard Worker 187*da0073e9SAndroid Build Coastguard Workerecho "Will install headers and libs to $INSTALL_PREFIX for further Android project usage." 188*da0073e9SAndroid Build Coastguard Workercmake --build . --target install -- "-j${MAX_JOBS}" 189*da0073e9SAndroid Build Coastguard Workerecho "Installation completed, now you can copy the headers/libs from $INSTALL_PREFIX to your Android project directory." 190