Skip to content

Latest commit

 

History

History
209 lines (174 loc) · 8.98 KB

build_android.md

File metadata and controls

209 lines (174 loc) · 8.98 KB

Build C++ utility libraries using Android NDK

This document describes how to build NNabla C++ libraries using Android Native Development Kit(NDK).
The following instruction demonstrates the build procedure on Ubuntu 20.04 using Android NDK.

Most of the procedure is same as Build C++ utility libraries.
There are two options to build NNabla for Android.

  • Quick build using Docker
  • Manual Build

Quick build using Docker

Execute the following command at the root directory of NNabla repository.

make bwd-nnabla-cpplib-android

The above make will build NNabla C++ libraries and its dependent libraries within android docker container.
After successful build, you can find the libraries under build-android/build_android-${PLATFORM}_${ARCHITECTURE}/${ABI} folder of your system. The docker container uses Android NDK version r25b by default.

You can change the parameters by adding the following arguments:

Parameter Default Value Description
ANDROID_NDKNAME android-ndk-r25b Android NDK package installed in docker image
ANDROID_PLATFORM android-33 Minimum Android API level supported by library
ANDROID_ARCHITECTURE arm64 Target architecture
ANDROID_CMAKE_SYSTEM_NAME aarch64-linux-android OS name for which cmake is to build
ANDROID_EABI arm64-v8a CPU architecture and instruction set for Android application binary interface

If you would like to support Oreo (API level 26), execute as follows:

make bwd-nnabla-cpplib-android ANDROID_PLATFORM=android-26

If you want to build docker image by yourself, then please refer build instructions of docker file at Android Dockerfile section

Manual Build

This section explains the manual building of NNabla using android NDK.

Requirements

Following build dependencies needs to be installed by the user manually.

  • G++: sudo apt-get install build-essential

  • CMake>=3.11: sudo apt-get install cmake

  • Python: sudo apt-get install python3.8 python3-pip (Used by code generator)

    • Python packages: sudo -H python3 -m pip install setuptools six pyyaml mako
  • curl, make and git: sudo apt-get install curl make git

  • Android NDK: Download the required NDK version from https://developer.android.com/ndk/downloads/. Extract the downloaded NDK into folder, and set ** ANDROID_NDK_HOME environment variable ** to specify this extracted directory. NNabla android build is tested with android-ndk-r25b, however the build should work with other NDK version as well.

  • Protobuf >=3: See next section.

  • libarchive: See next section.

Installing protobuf3 and libarchive C++ libraries and tools

Protobuf: Install from source.

Unlike Python Package compilation which requires protoc compiler only, the NNabla C++ utility library requires protobuf C++ library too. The following snippet running on your terminal will build and install protobuf-3.20.3 from source.

curl -L https://github.com/google/protobuf/archive/v3.20.3.tar.gz -o protobuf-v3.20.3.tar.gz
tar xvf protobuf-v3.20.3.tar.gz
cd protobuf-3.20.3
mkdir build build-android
cd build
cmake -DCMAKE_POSITION_INDEPENDENT_CODE=ON -Dprotobuf_BUILD_TESTS=OFF -DCMAKE_CXX_STANDARD=14 ../cmake
make -j
sudo make install  # See a note below if you want your system clean.
cd ..

cd build-android
cmake \
    -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake  \
    -DANDROID_ABI=arm64-v8a \
    -DCMAKE_SYSTEM_NAME=aarch64-linux-android \
    -DANDROID_STL=c++_shared \
    -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
    -Dprotobuf_BUILD_TESTS=OFF \
    -DBUILD_SHARED_LIBS=ON \
    -DCMAKE_INSTALL_PREFIX=/usr/local/android/arm64 \
    ../cmake
$ANDROID_NDK_HOME/prebuilt/linux-x86_64/bin/make -j
sudo $ANDROID_NDK_HOME/prebuilt/linux-x86_64/bin/make install

NOTE: Installing protobuf on your system with sudo may harm a protobuf library previously installed on your system. It is recommended to install a protobuf to a user folder. Specify a cmake option -DCMAKE_INSTALL_PREFIX=<installation path> to set your preferred installation path (e.g. $HOME/nnabla_build_deps), and run make install without sudo. In the NNabla C++ library compilation described below, to help CMake system find the protobuf, pass the installation path to an environment variable CMAKE_FIND_ROOT_PATH. NNabla's CMake script is written to use the value (multiple paths can be passed with a delimiter ;, e.g. CMAKE_FIND_ROOT_PATH="<path A>;<path B>";${CMAKE_FIND_ROOT_PATH}) as search paths to find some packages (e.g. protobuf, hdf5, libarchive) on your system. Please don't forget to set environment variables such as a executable path and library paths (e.g. PATH, LD_LIBRARY_PATH etc) if you have runtime dependencies at your custom installation path.

Protobuf: Install from PPA package.

Here is the procedure using an informal PPA package. If you can not trust unofficial packages, please use the procedure to build from the source shown above.

sudo add-apt-repository ppa:maarten-fonville/protobuf
sudo apt install protobuf-compiler libprotoc-dev libprotobuf-dev
libarchive: Install from source.

NNabla C++ utility library requires libarchive C++ library. The following snippet running on your terminal will build and install libarchive-3.3.2 from source.

curl -LO https://www.libarchive.org/downloads/libarchive-3.3.2.tar.gz
tar xzf libarchive-3.3.2.tar.gz
cd libarchive-3.3.2
sed -i "/INCLUDE(CheckTypeSize)/aINCLUDE_DIRECTORIES($(pwd)/contrib/android/include/)" CMakeLists.txt
cmake  \
    -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake \
    -DANDROID_ABI=arm64-v8a \
    -DCMAKE_SYSTEM_NAME=aarch64-linux-android \
    -DANDROID_STL=c++_shared \
    -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
    -DCMAKE_INSTALL_PREFIX=/usr/local/android/arm64 \
    -DENABLE_TEST=OFF \
    .
sed -i "/#include \"passphrase.h\"/a#ifdef ANDROID\nint wctomb(char *s, wchar_t wc) { return wcrtomb(s,wc,NULL); }\nint mbtowc(wchar_t *pwc, const char *s, size_t n) { return mbrtowc(pwc, s, n, NULL); }\n#endif" tar/util.c
$ANDROID_NDK_HOME/prebuilt/linux-x86_64/bin/make -j
sudo $ANDROID_NDK_HOME/prebuilt/linux-x86_64/bin/make install
sudo cp contrib/android/include/* /usr/local/android/arm64/include/

Build

To build NNabla using Android NDK, first clone the NNabla repository from github, then cmake and make.

git clone https://github.com/sony/nnabla
mkdir nnabla/build
cd nnabla/build
cmake \
    -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake \
    -DANDROID_ABI=arm64-v8a \
    -DANDROID_PLATFORM=android-33 \
    -DCMAKE_SYSTEM_NAME=aarch64-linux-android \
    -DANDROID_STL=c++_shared \
    -DBUILD_CPP_UTILS=ON \
    -DBUILD_PYTHON_PACKAGE=OFF \
    ..
$ANDROID_NDK_HOME/prebuilt/linux-x86_64/bin/make -j

After successful build, you can find libnnabla.so and libnnabla_utils.so under build/lib folder of your system.

Test

We can verify the NNabla C++ android libraries by running the sample application in the native layer. To do so, we need to first setup required environment as follows:

  • Download and setup android studio, please refer here for details.
  • Add the android SDK's platform-tools folder location to path variable. E.g. export PATH=$PATH:/home/nnabla/Android/Sdk/platform-tools
  • Launch emulator using AVD with suitable platform and architecture or Connect android device with USB debugging option enabled. To verify the device or emulator running , please type following command: $adb devices Your device/emulator should be listed as shown in following example.
$ adb devices
List of devices attached
CB5A2AG8N7	device

NNabla android build script also compiles mnist_runtime example program located in here. The executable can be found at build-android/bin/mnist_runtime on successful build of NNabla. Follow the instructions present here for creating the nnp file which is required for c++ inferring.

Execute the following commands to run the mnist c++ inferring sample program in native layer.

$adb push build-android/bin/mnist_runtime /data/local/tmp/
$adb push examples/cpp/mnist_runtime/lenet_010000.nnp /data/local/tmp/
$adb push examples/cpp/mnist_runtime/5.pgm /data/local/tmp/
$adb push build-android/build_${platform}_${architecture}/${ABI}/. /data/local/tmp/
$adb shell
$cd /data/local/tmp
$export LD_LIBRARY_PATH=/data/local/tmp
$./mnist_runtime lenet_010000.nnp 5.pgm

You should see output as follows:

SO-03H:/data/local/tmp $ ./mnist_runtime lenet_010000.nnp 5.pgm
Executing...
Prediction scores: -18.3584 -23.4614 -10.6035 8.44051 -9.19585 43.2856 5.42506 -19.7537 13.8561 -3.35031
Prediction: 5

Congratulations your android build is successful!