Build PaddlePaddle for Android¶
There are two approaches to build PaddlePaddle for Android: using Docker and on Linux without Docker.
Cross-Compiling Using Docker¶
Docker-based cross-compiling is the recommended approach because Docker runs on all major operating systems, including Linux, Mac OS X, and Windows.
Build the Docker Image¶
The following steps pack all the tools that we need to build PaddlePaddle into a Docker image.
$ git clone https://github.com/PaddlePaddle/Paddle.git
$ cd Paddle
$ docker build -t paddle:dev-android . -f Dockerfile.android
Build the Inference Library¶
We can run the Docker image we just created to build the inference library of PaddlePaddle for Android using the command below:
$ docker run -it --rm -v $PWD:/paddle -e "ANDROID_ABI=armeabi-v7a" -e "ANDROID_API=21" paddle:dev-android
The Docker image accepts two arguments ANDROID_ABI
and ANDROID_API
:
Argument | Optional Values | Default |
---|---|---|
ANDROID_ABI | armeabi-v7a, arm64-v8a | armeabi-v7a |
ANDROID_API | >= 21 | 21 |
The ARM-64 architecture (arm64-v8a
) requires at least level 21 of Android API.
The default entry-point of the Docker image, paddle/scripts/docker/build_android.sh
generates the Android cross-compiling standalone toolchain based on the argument: ANDROID_ABI
or ANDROID_API
. For information about other configuration arguments, please continue reading.
The above command generates and outputs the inference library in $PWD/install_android
and puts third-party libraries in $PWD/install_android/third_party
.
Cross-Compiling on Linux¶
The Linux-base approach to cross-compile is to run steps in Dockerfile.android
manually on a Linux x64 computer.
Setup the Environment¶
To build for Android’s, we need Android NDK:
wget -q https://dl.google.com/android/repository/android-ndk-r14b-linux-x86_64.zip
unzip -q android-ndk-r14b-linux-x86_64.zip
Android NDK includes everything we need to build the standalone toolchain, which in then used to build PaddlePaddle for Android. (We plan to remove the intermediate stage of building the standalone toolchain in the near future.)
To build the standalone toolchain for
armeabi-v7a
and Android API level 21:your/path/to/android-ndk-r14b-linux-x86_64/build/tools/make-standalone-toolchain.sh \ --arch=arm --platform=android-21 --install-dir=your/path/to/arm_standalone_toolchain
The generated standalone toolchain will be in
your/path/to/arm_standalone_toolchain
.To build the standalone toolchain for
arm64-v8a
and Android API level 21:your/path/to/android-ndk-r14b-linux-x86_64/build/tools/make-standalone-toolchain.sh \ --arch=arm64 --platform=android-21 --install-dir=your/path/to/arm64_standalone_toolchain
The generated standalone toolchain will be in
your/path/to/arm64_standalone_toolchain
.
Please be aware that the minimum level of Android API required by PaddlePaddle is 21.
Cross-Compiling Arguments¶
CMake supports choosing the toolchain. PaddlePaddle provides android.cmake
, which configures the Android cross-compiling toolchain for CMake. android.cmake
is not required for CMake >= 3.7, which support Android cross-compiling. PaddlePaddle detects the CMake version, for those newer than 3.7, it uses the official version.
Some other CMake arguments you need to know:
CMAKE_SYSTEM_NAME
must beAndroid
. This tells PaddlePaddle’s CMake system to cross-compile third-party dependencies. This also changes some other CMake arguments likeWITH_GPU=OFF
,WITH_AVX=OFF
,WITH_PYTHON=OFF
, andWITH_RDMA=OFF
.WITH_C_API
must beON
, to build the C-based inference library for Android.WITH_SWIG_PY
must beOFF
because the Android platform doesn’t support SWIG-based API.
Some Android-specific arguments:
ANDROID_STANDALONE_TOOLCHAIN
: the absolute path of the Android standalone toolchain, or the path relative to the CMake build directory. PaddlePaddle’s CMake extensions would derive the cross-compiler, sysroot and Android API level from this argument.ANDROID_TOOLCHAIN
: could begcc
orclang
. The default value isclang
.- For CMake >= 3.7, it should anyway be
clang
. For older versions, it could begcc
. - Android’s official
clang
requiresglibc
>= 2.15.
- For CMake >= 3.7, it should anyway be
ANDROID_ABI
: could bearmeabi-v7a
orarm64-v8a
. The default value isarmeabi-v7a
.ANDROID_NATIVE_API_LEVEL
: could be derived from the value ofANDROID_STANDALONE_TOOLCHAIN
.ANROID_ARM_MODE
:- could be
ON
orOFF
, and defaults toON
, whenANDROID_ABI=armeabi-v7a
; - no need to specify when
ANDROID_ABI=arm64-v8a
.
- could be
ANDROID_ARM_NEON
: indicates if to use NEON instructions.- could be
ON
orOFF
, and defaults toON
, whenANDROID_ABI=armeabi-v7a
; - no need to specify when
ANDROID_ABI=arm64-v8a
.
- could be
Other useful arguments:
USE_EIGEN_FOR_BLAS
: indicates if using Eigen. Could beON
orOFF
, defaults toOFF
.HOST_C/CXX_COMPILER
: specifies the host compiler, which is used to build the host-specific protoc and target-specific OpenBLAS. It defaults to the value of the environment variableCC
, orcc
.
Some frequent configurations for your reference:
cmake -DCMAKE_SYSTEM_NAME=Android \
-DANDROID_STANDALONE_TOOLCHAIN=your/path/to/arm_standalone_toolchain \
-DANDROID_ABI=armeabi-v7a \
-DANDROID_ARM_NEON=ON \
-DANDROID_ARM_MODE=ON \
-DUSE_EIGEN_FOR_BLAS=ON \
-DCMAKE_INSTALL_PREFIX=your/path/to/install \
-DWITH_C_API=ON \
-DWITH_SWIG_PY=OFF \
..
cmake -DCMAKE_SYSTEM_NAME=Android \
-DANDROID_STANDALONE_TOOLCHAIN=your/path/to/arm64_standalone_toolchain \
-DANDROID_ABI=arm64-v8a \
-DUSE_EIGEN_FOR_BLAS=OFF \
-DCMAKE_INSTALL_PREFIX=your/path/to/install \
-DWITH_C_API=ON \
-DWITH_SWIG_PY=OFF \
..
There are some other arguments you might want to configure.
CMAKE_BUILD_TYPE=MinSizeRel
minimizes the size of library.CMAKE_BUILD_TYPE-Release
optimizes the runtime performance.
Our own tip for performance optimization to use clang and Eigen or OpenBLAS:
CMAKE_BUILD_TYPE=Release
ANDROID_TOOLCHAIN=clang
USE_EIGEN_BLAS=ON
forarmeabi-v7a
, orUSE_EIGEN_FOR_BLAS=OFF
forarm64-v8a
.
Build and Install¶
After running cmake
, we can run make; make install
to build and install.
Before building, you might want to remove the third_party
and build
directories including pre-built libraries for other architectures.
After building,in the directory CMAKE_INSTALL_PREFIX
, you will find three sub-directories:
include
: the header file of the inference library,lib
: the inference library built for various Android ABIs,third_party
: dependent third-party libraries built for Android.