11# 构建Android平台上的PaddlePaddle库
22
3- 用户可通过交叉编译的方式,在用户熟悉的开发平台(Linux,Mac OS X和Windows)上编译Android平台上适用的PaddlePaddle库。
3+ 用户可通过如下两种方式,交叉编译Android平台上适用的PaddlePaddle库:
4+ - 基于Docker容器的编译方式
5+ - 基于Linux交叉编译环境的编译方式
6+
7+ ## 基于Docker容器的编译方式
8+ Docker能在所有主要操作系统(包括Linux,Mac OS X和Windows)上运行,因此,使用基于Docker容器的编译方式,用户可在自己熟悉的开发平台上编译Android平台上适用的PaddlePaddle库。
9+
10+ ### 构建PaddlePaddle的Android开发镜像
11+ 我们把PaddlePaddle的交叉编译环境打包成一个镜像,称为开发镜像,里面涵盖了交叉编译Android版PaddlePaddle库需要的所有编译工具。
12+
13+ ``` bash
14+ $ git clone https://github.com/PaddlePaddle/Paddle.git
15+ $ cd Paddle
16+ $ docker build -t username/paddle-android:dev . -f Dockerfile.android
17+ ```
18+
19+ ### 编译PaddlePaddle C-API库
20+ 构建好开发镜像后,即可使用开发镜像来编译Android版PaddlePaddle C-API库。
21+ Android的Docker开发镜像向用户提供两个可配置的参数:
22+
23+ | Argument | Optional Values | Default |
24+ | -----------------| -------------------------| ---------|
25+ | ` ANDROID_ABI ` | ` armeabi-v7a, arm64-v8a ` | ` armeabi-v7a ` |
26+ | ` ANDROID_API ` | ` >= 21 ` | ` 21 ` |
27+
28+ - 编译` armeabi-v7a ` ,` Android API 21 ` 的PaddlePaddle库
29+ ``` bash
30+ $ docker run -it --rm -v $PWD :/paddle -e " ANDROID_ABI=armeabi-v7a" -e " ANDROID_API=21" username/paddle-android:dev
31+ ```
32+
33+ - 编译` arm64-v8a ` ,` Android API 21 ` 的PaddlePaddle库
34+ ``` bash
35+ $ docker run -it --rm -v $PWD :/paddle -e " ANDROID_ABI=arm64-v8a" -e " ANDROID_API=21" username/paddle-android:dev
36+ ```
37+
38+ 执行上述` docker run ` 命令时,容器默认执行[ paddle/scripts/docker/build_android.sh] ( https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/scripts/docker/build_android.sh ) 脚本。该脚本中记录了交叉编译Android版PaddlePaddle库常用的CMake配置,并且会根据` ANDROID_ABI ` 和` ANDROID_API ` 自动构建独立工具链、进行编译和安装。由于arm64架构要求Android API不小于21。因此当` ANDROID_ABI=arm64-v8a ` ,` ANDROID_API<21 ` 时,Docker容器中将默认使用` Android API 21 ` 的编译工具链。用户可以参考下文** 配置交叉编译参数** 章节,根据个人的需求修改定制Docker容器所执行的脚本。编译安装结束之后,PaddlePaddle的C-API库将被安装到` $PWD/install_android ` 目录,所依赖的第三方库同时也被安装到` $PWD/install_android/third_party ` 目录。
39+
40+ ## 基于Linux交叉编译环境的编译方式
441本文档将以Linux x86-64平台为例,介绍交叉编译Android平台上适用的PaddlePaddle库的方法和步骤。
542
6- ## 准备交叉编译环境
43+ ### 准备交叉编译环境
744
845从源码交叉编译PaddlePaddle,用户需要提前准备好交叉编译环境。Android平台上使用的C/C++交叉编译工具链为[ Android NDK] ( https://developer.android.com/ndk/downloads/index.html?hl=zh-cn ) ,用户可自行前往下载预编译好的版本,也可通过以下命令获取:
946
@@ -13,18 +50,27 @@ unzip -q android-ndk-r14b-linux-x86_64.zip
1350```
1451
1552Android NDK中包含了所有Android API级别、所有架构(arm/arm64/x86/mips)需要用到的编译工具和系统库。用户可根据自己的编译目标架构、所需支持的最低Android API级别,构建[ 独立工具链] ( https://developer.android.google.cn/ndk/guides/standalone_toolchain.html?hl=zh-cn ) 。
16- 比如:
53+
54+ - 构建` armeabi-v7a ` 、 ` Android API 21 ` 的独立工具链:
1755
1856``` bash
1957your/path/to/android-ndk-r14b-linux-x86_64/build/tools/make-standalone-toolchain.sh \
20- --arch=arm --platform=android-21 --install-dir=your/path/to/my_standalone_toolchain
58+ --arch=arm --platform=android-21 --install-dir=your/path/to/arm_standalone_toolchain
2159```
2260
23- 此命令将在your /path/to/my_standalone_toolchain目录生成一套编译工具链 ,面向架构为32位ARM架构,支持的最小的Android API级别为21,使用的编译器为arm -linux-androideabi-gcc (GCC) 4.9。
61+ 此命令将在 ` your /path/to/arm_standalone_toolchain ` 目录生成一套独立编译工具链 ,面向架构为32位ARM架构,支持的最小的Android API级别为21,支持编译器 ` arm -linux-androideabi-gcc (GCC) 4.9` 和 ` clang 3.8 ` 。
2462
25- 注意:** PaddlePaddle要求使用的编译工具链所支持的Andoid API级别不小于21** 。
63+ - 构建` arm64-v8a ` 、 ` Android API 21 ` 的独立工具链:
64+ ``` bash
65+ your/path/to/android-ndk-r14b-linux-x86_64/build/tools/make-standalone-toolchain.sh \
66+ --arch=arm64 --platform=android-21 --install-dir=your/path/to/arm64_standalone_toolchain
67+ ```
2668
27- ## 配置交叉编译参数
69+ 此命令将在` your/path/to/arm64_standalone_toolchain ` 目录生成一套独立编译工具链,面向架构为64位ARM64架构,支持的最小Android API级别为21,支持编译器` arm-linux-androideabi-gcc (GCC) 4.9 ` 和` clang 3.8 ` 。
70+
71+ 注意:** PaddlePaddle要求使用的编译工具链所支持的Android API级别不小于21** 。
72+
73+ ### 配置交叉编译参数
2874
2975CMake系统对交叉编译提供了支持[ cmake-toolchains] ( https://cmake.org/cmake/help/v3.0/manual/cmake-toolchains.7.html#cross-compiling ) 。为了简化cmake配置,PaddlePaddle为交叉编译提供了工具链配置文档[ cmake/cross_compiling/android.cmake] ( https://github.com/PaddlePaddle/Paddle/blob/develop/cmake/cross_compiling/android.cmake ) ,以提供一些默认的编译器和编译参数相关配置。注意,从CMake 3.7版本开始,CMake官方对Android平台的交叉编译提供了通用的支持。PaddlePaddle若检测到用户使用的CMake版本不低于3.7时,将会将用户传进来的配置参数传递CMake系统,交由CMake系统本身来处理。有关参数配置的详细说明见[ cmake-toolchains] ( https://cmake.org/cmake/help/v3.7/manual/cmake-toolchains.7.html#cross-compiling ) 。
3076
@@ -36,32 +82,57 @@ CMake系统对交叉编译提供了支持[cmake-toolchains](https://cmake.org/cm
3682Android平台可选配置参数:
3783
3884- ` ANDROID_STANDALONE_TOOLCHAIN ` ,独立工具链所在的绝对路径,或者相对于构建目录的相对路径。PaddlePaddle的CMake系统将根据该值自动推导和设置需要使用的交叉编译器、sysroot、以及Android API级别;否则,用户需要在cmake时手动设置这些值。无默认值。
39- - ` ANDROID_ABI ` ,目标架构ABI。目前只支持` armeabi-v7a ` ,默认值为` armeabi-v7a ` 。
85+ - ` ANDROID_TOOLCHAIN ` ,目标工具链。可设置` gcc/clang ` ,默认值为` clang ` 。
86+ - CMake 3.7以上,将会始终使用`clang`工具链;CMake 3.7以下,可设置`ANDROID_TOOLCHAIN=gcc`以使用`gcc`工具链。
87+ - Android官方提供的`clang`编译器要求系统支持`GLIBC 2.15`以上。
88+ - ` ANDROID_ABI ` ,目标架构ABI。目前支持` armeabi-v7a ` 和` arm64-v8a ` ,默认值为` armeabi-v7a ` 。
4089- ` ANDROID_NATIVE_API_LEVEL ` ,工具链的Android API级别。若没有显式设置,PaddlePaddle将根据` ANDROID_STANDALONE_TOOLCHAIN ` 的值自动推导得到。
41- - ` ANROID_ARM_MODE ` ,是否使用ARM模式。可设置` ON/OFF ` ,默认值为` ON ` 。
42- - ` ANDROID_ARM_NEON ` ,是否使用NEON指令。目前必须设置成` ON ` ,默认值为` ON ` 。
90+ - ` ANROID_ARM_MODE ` ,是否使用ARM模式。
91+ - `ANDROID_ABI=armeabi-v7a`时,可设置`ON/OFF`,默认值为`ON`;
92+ - `ANDROID_ABI=arm64-v8a`时,不需要设置。
93+ - ` ANDROID_ARM_NEON ` ,是否使用NEON指令。
94+ - `ANDROID_ABI=armeabi-v7a`时,可设置`ON/OFF`,默认值为`ON`;
95+ - `ANDROID_ABI=arm64-v8a`时,不需要设置。
4396
4497其他配置参数:
4598
99+ - ` USE_EIGEN_FOR_BLAS ` ,是否使用Eigen库进行矩阵计算。可设置` ON/OFF ` ,默认值为` OFF ` 。
46100- ` HOST_C/CXX_COMPILER ` ,宿主机的C/C++编译器。在编译宿主机版protoc可执行文件和目标机版OpenBLAS库时需要用到。默认设置成环境变量` CC ` 的值;若环境变量` CC ` 没有设置,则设置成` cc ` 编译器。
47101
48- 一种常用的cmake配置如下 :
102+ 常用的cmake配置如下 :
49103
50104``` bash
51105cmake -DCMAKE_SYSTEM_NAME=Android \
52- -DANDROID_STANDALONE_TOOLCHAIN=your/path/to/my_standalone_toolchain \
106+ -DANDROID_STANDALONE_TOOLCHAIN=your/path/to/arm_standalone_toolchain \
53107 -DANDROID_ABI=armeabi-v7a \
54108 -DANDROID_ARM_NEON=ON \
55109 -DANDROID_ARM_MODE=ON \
110+ -DUSE_EIGEN_FOR_BLAS=ON \
56111 -DCMAKE_INSTALL_PREFIX=your/path/to/install \
57112 -DWITH_C_API=ON \
58113 -DWITH_SWIG_PY=OFF \
59114 ..
60115```
61116
117+ ```
118+ cmake -DCMAKE_SYSTEM_NAME=Android \
119+ -DANDROID_STANDALONE_TOOLCHAIN=your/path/to/arm64_standalone_toolchain \
120+ -DANDROID_ABI=arm64-v8a \
121+ -DUSE_EIGEN_FOR_BLAS=OFF \
122+ -DCMAKE_INSTALL_PREFIX=your/path/to/install \
123+ -DWITH_C_API=ON \
124+ -DWITH_SWIG_PY=OFF \
125+ ..
126+ ```
127+
62128用户还可根据自己的需求设置其他编译参数。比如希望最小化生成的库的大小,可以设置` CMAKE_BUILD_TYPE ` 为` MinSizeRel ` ;若希望最快的执行速度,则可设置` CMAKE_BUILD_TYPE ` 为` Release ` 。亦可以通过手动设置` CMAKE_C/CXX_FLAGS_MINSIZEREL/RELEASE ` 来影响PaddlePaddle的编译过程。
63129
64- ## 编译和安装
130+ ** 性能TIPS** ,为了达到最快的计算速度,在CMake参数配置上,有以下建议:
131+ - 设置` CMAKE_BUILD_TYPE ` 为` Release `
132+ - 使用` clang ` 编译工具链
133+ - ` armeabi-v7a ` 时,设置` USE_EIGEN_BLAS=ON ` ,使用Eigen进行矩阵计算;` arm64-v8a ` 时,设置` USE_EIGEN_FOR_BLAS=OFF ` ,使用OpenBLAS进行矩阵计算
134+
135+ ### 编译和安装
65136
66137CMake配置完成后,执行以下命令,PaddlePaddle将自动下载和编译所有第三方依赖库、编译和安装PaddlePaddle预测库。
67138
@@ -72,4 +143,4 @@ make install
72143
73144注意:如果你曾经在源码目录下编译过其他平台的PaddlePaddle库,请先使用` rm -rf ` 命令删除` third_party ` 目录和` build ` 目录,以确保所有的第三方依赖库和PaddlePaddle代码都是针对新的CMake配置重新编译的。
74145
75- 执行完安装命令后,` your/path/to/install ` 目录中会包含` include ` 和 ` lib ` 目录,其中` include ` 中包含C-API的头文件,` lib ` 中包含一个Android版本的库 。自此,PaddlePaddle的已经安装完成,用户可将` your/path/to/install ` 目录下的生成文件用于深度学习相关Android App中,调用方法见C-API文档。
146+ 执行完安装命令后,` your/path/to/install ` 目录中会包含` include ` 、 ` lib ` 和 ` third_party ` 目录,其中` include ` 中包含C-API的头文件,` lib ` 中包含若干个不同Android ABI的PaddlePaddle库, ` third_party ` 中包含所依赖的所有第三方库 。自此,PaddlePaddle的已经安装完成,用户可将` your/path/to/install ` 目录下的生成文件用于深度学习相关Android App中,调用方法见C-API文档。
0 commit comments