Skip to content

Latest commit

 

History

History
170 lines (129 loc) · 5.35 KB

cross_build_snpe_service.md

File metadata and controls

170 lines (129 loc) · 5.35 KB

Ubuntu18.04 交叉编译 NDK snpe 推理服务

mmdeploy 已提供预编译包,如果你想自己编译、或需要对 .proto 接口做修改,可参考此文档。

注意 gRPC 官方文档并没有对 NDK 的完整支持。

一、环境说明

项目 版本 备注
snpe 1.59 1.60 使用 clang-8.0,可能导致兼容问题
host OS ubuntu18.04 snpe1.59 指定版本
NDK r17c snpe1.59 指定版本
gRPC commit 6f698b5 -
硬件设备 qcom888 需要 qcom 芯片

二、NDK 交叉编译 gRPC

  1. 拉取 gRPC repo, 在 host 上编译出 protocgrpc_cpp_plugin
# 安装依赖
$ apt-get update && apt-get install -y libssl-dev
# 编译
$ git clone https://github.com/grpc/grpc --recursive=1 --depth=1
$ mkdir -p cmake/build
$ pushd cmake/build

$ cmake \
  -DCMAKE_BUILD_TYPE=Release \
  -DgRPC_INSTALL=ON \
  -DgRPC_BUILD_TESTS=OFF \
  -DgRPC_SSL_PROVIDER=package \
  ../..
# 需要安装到 host 环境
$ make -j
$ sudo make install
  1. 下载 NDK,交叉编译 android aarch64 所需静态库
$ wget https://dl.google.com/android/repository/android-ndk-r17c-linux-x86_64.zip
$ unzip android-ndk-r17c-linux-x86_64.zip

# 设置环境变量
$ export ANDROID_NDK=/path/to/android-ndk-r17c

# 编译
$ cd /path/to/grpc
$ mkdir -p cmake/build_aarch64  && pushd cmake/build_aarch64

$ cmake ../.. \
 -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \
 -DANDROID_ABI=arm64-v8a \
 -DANDROID_PLATFORM=android-26 \
 -DANDROID_TOOLCHAIN=clang \
 -DANDROID_STL=c++_shared \
 -DCMAKE_BUILD_TYPE=Release \
 -DCMAKE_INSTALL_PREFIX=/tmp/android_grpc_install_shared

$ make -j
$ make install
  1. 此时 /tmp/android_grpc_install 应有完整的安装文件
$ cd /tmp/android_grpc_install
$ tree -L 1
.
├── bin
├── include
├── lib
└── share

三、【可跳过】自测 NDK gRPC 是否正常

  1. 编译 gRPC 自带的 helloworld
$ cd /path/to/grpc/examples/cpp/helloworld/
$ mkdir cmake/build_aarch64 -p && pushd cmake/build_aarch64

$ cmake ../.. \
 -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \
 -DANDROID_ABI=arm64-v8a \
 -DANDROID_PLATFORM=android-26 \
 -DANDROID_STL=c++_shared \
 -DANDROID_TOOLCHAIN=clang \
 -DCMAKE_BUILD_TYPE=Release \
 -Dabsl_DIR=/tmp/android_grpc_install_shared/lib/cmake/absl \
 -DProtobuf_DIR=/tmp/android_grpc_install_shared/lib/cmake/protobuf \
 -DgRPC_DIR=/tmp/android_grpc_install_shared/lib/cmake/grpc

$ make -j
$ ls greeter*
greeter_async_client   greeter_async_server     greeter_callback_server  greeter_server
greeter_async_client2  greeter_callback_client  greeter_client
  1. 打开手机调试模式,push 编译结果到 /data/local/tmp 目录

tips:对于国产手机,设置 - 版本号,点击 7 次可进入开发者模式,然后才能打开 USB 调试

$ adb push greeter* /data/local/tmp
  1. adb shell 进手机,执行 client/server
/data/local/tmp $ ./greeter_client
Greeter received: Hello world

四、交叉编译 snpe 推理服务

  1. 打开 snpe tools 官网,下载 1.59 版本。 解压并设置环境变量

注意 snpe >= 1.60 开始使用 clang-8.0,可能导致旧设备与 libc++_shared.so 不兼容。

$ export SNPE_ROOT=/path/to/snpe-1.59.0.3230
  1. 打开 mmdeploy snpe server 目录,使用交叉编译 gRPC 时的选项
$ cd /path/to/mmdeploy
$ cd service/snpe/server

$ mkdir -p build && cd build
$ export ANDROID_NDK=/path/to/android-ndk-r17c
$ cmake .. \
 -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake \
 -DANDROID_ABI=arm64-v8a \
 -DANDROID_PLATFORM=android-26 \
 -DANDROID_STL=c++_shared \
 -DANDROID_TOOLCHAIN=clang \
 -DCMAKE_BUILD_TYPE=Release \
 -Dabsl_DIR=/tmp/android_grpc_install_shared/lib/cmake/absl \
 -DProtobuf_DIR=/tmp/android_grpc_install_shared/lib/cmake/protobuf \
 -DgRPC_DIR=/tmp/android_grpc_install_shared/lib/cmake/grpc

 $ make -j
 $ file inference_server
inference_server: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, BuildID[sha1]=252aa04e2b982681603dacb74b571be2851176d2, with debug_info, not stripped

最终可得到 infernece_serveradb push 到设备上即可执行。

五、重新生成 proto 接口

如果改过 inference.proto,需要重新生成 .cpp 和 .py 通信接口

$ python3 -m pip install grpc_tools --user
$ python3 -m  grpc_tools.protoc -I./ --python_out=./client/ --grpc_python_out=./client/ inference.proto

$ ln -s `which protoc-gen-grpc`
$ protoc --cpp_out=./ --grpc_out=./  --plugin=protoc-gen-grpc=grpc_cpp_plugin  inference.proto

参考文档