Is it possible to build and use Valhalla v3 on Android
Hi Is it possible to build and use Valhalla v3 on Android? Is there any instructions on how to do this?
Thanks
It is possible but there are no instructions. Different applications likely have different needs and ways they want to interface with Valhalla. gradle allows CMake so it isn't too hard to generate a native C++ build of Valhalla on the target Android platform. The real work is generating JNI and supporting calls on the Valhalla side for each of the "actions" that are needed.
The below in an excerpt from a build instructions document for android platform.
It builds libvalhalla 3.0, tested with protobuf 3.6.0 and boost 1.68.0
I have another lib on top, static links everything, and planing on exposing it via JNI. much simpler than exposing valhalla directly.
mkdir build-android && cd build-android
export BUILD_DIR=`pwd`
export ANDROID_SDK=~/Android/Sdk
export NDK=$ANDROID_SDK/ndk-bundle
# https://developer.android.com/ndk/guides/standalone_toolchain
# Create an arm API 28 libc++ toolchain.
$NDK/build/tools/make_standalone_toolchain.py \
--arch arm \
--api 28 \
--install-dir=android-toolchain
# Add the standalone toolchain to the search path.
export PATH=$PATH:`pwd`/android-toolchain/bin
# Tell configure what tools to use.
export target_host=arm-linux-androideabi
export AR=$target_host-ar
export CMAKE_AR=$target_host-ar
export AS=$target_host-clang
export CC=$target_host-clang
export CXX=$target_host-clang++
export LD=$target_host-ld
export STRIP=$target_host-strip
export SYSROOT=`pwd`/android-toolchain/sysroot
# Tell configure what flags Android requires.
export CFLAGS="-fPIE -fPIC"
export LDFLAGS="-pie"
#------------------------#
#---- Build protobuf ----#
#------------------------#
cd ../externals/protobuf/ && export PROTOBUF_INC_PATH=`pwd`/src && ./autogen.sh
cd $BUILD_DIR
mkdir protobuf && cd protobuf
# make sure that the protoc executable you use has the same version as the protobuf source code
# build protobuf for host to get the executable protoc
mkdir host && cd host
env -i PATH=$PATH ../../../externals/protobuf/configure --host=x86_64-pc-linux-gnu
make -j$(nproc)
export PROTOBUF_PROTOC_PATH=`pwd`/src
cd ..
# build protobuf for target with protoc from host
../../externals/protobuf/configure --host=$target_host --enable-static --disable-shared --with-protoc=./host/src/protoc LDFLAGS="$LDFLAGS -llog"
make -j$(nproc)
export PROTOBUF_PATH=`pwd`/src
cd ..
#-------------------#
#---- Get boost ----#
#-------------------#
mkdir boost && cd boost
export BOOST_VERSION=1.68.0
export BOOST_VERSION_UNDERSCORE="${BOOST_VERSION//./_}"
wget https://dl.bintray.com/boostorg/release/$BOOST_VERSION/source/boost_$BOOST_VERSION_UNDERSCORE.tar.gz
tar -xf boost_$BOOST_VERSION_UNDERSCORE.tar.gz
export BOOST_ROOT=`pwd`/boost_$BOOST_VERSION_UNDERSCORE
cd ..
#------------------------#
#---- Build valhalla ----#
#------------------------#
mkdir valhalla && cd valhalla
export VALHALLA_DIR=absolute/path/to/valhalla/directory
export VALHALLA_BUILD_DIR=`pwd`
cmake \
-DCMAKE_BUILD_TYPE=Release -DENABLE_TOOLS=Off -DENABLE_DATA_TOOLS=Off -DENABLE_PYTHON_BINDINGS=Off -DENABLE_NODE_BINDINGS=Off -DENABLE_HTTP=Off -DENABLE_SERVICES=Off \
-DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DANDROID_PLATFORM=android-28 \
-DProtobuf_INCLUDE_DIR=$PROTOBUF_INC_PATH -DProtobuf_LIBRARIES=$PROTOBUF_PATH \
-DProtobuf_PROTOC_EXECUTABLE=$PROTOBUF_PROTOC_PATH/protoc \
-DBoost_INCLUDE_DIR=$BOOST_ROOT \
-DCMAKE_CXX_FLAGS=-isystem\ $BOOST_ROOT\ -isystem\ /$PROTOBUF_INC_PATH \
$VALHALLA_DIR/.
make -j$(nproc)
cd ..
Couple of amendments to the above to enable (eventually) linking against static libs across android targets/archs
export CFLAGS="-fpie -fpic -O3"
export CXXFLAGS="-fpie -fpic -O3"
export CPPFLAGS="-fpie -fpic -O3"
# build protobuf for target with protoc from host
../../externals/protobuf/configure --host=$target_host --enable-static --disable-shared --with-protoc=./host/src/protoc LDFLAGS="$LDFLAGS -llog" --with-pic
Hi, @aborovac I have successfully compiled the library by your android shell commands. The library is more than 200mb, is it the expected size level? How can I shrink the libvalhalla.a static lib?
Stripping worked for me to reduce size. Sorry, don't have exact command at hand. Perhaps the best is to strip the final binary that is using the static library.
What's the size after stripping?
It becomes 18mb after running strip -s libvalhalla.a
I was stripping binary program that used libvalhalla, and the program had final size ~10 MB for Android.
@aborovac could you please share your JNI code ?
@aborovac could you please share your JNI code ?
I've never done it myself.
Hi All, Having the same problem trying to build the valhalla native lib for android - and the script above no longer works. Anyone able to compile the lib for android lately?
Thanks
lots of people are doing this we just don't have it as part of our build yet. there is an issue issue that talks about cross compiling for both mobile targets https://github.com/valhalla/valhalla/issues/373#issuecomment-881683496
I wanted to add support for this in ci but just haven't had the time. too busy these days
mkdir build-android && cd build-android export BUILD_DIR=`pwd` export ANDROID_SDK=~/Android/Sdk export NDK=$ANDROID_SDK/ndk-bundle # https://developer.android.com/ndk/guides/standalone_toolchain # Create an arm API 28 libc++ toolchain. $NDK/build/tools/make_standalone_toolchain.py \ --arch arm \ --api 28 \ --install-dir=android-toolchain # Add the standalone toolchain to the search path. export PATH=$PATH:`pwd`/android-toolchain/bin # Tell configure what tools to use. export target_host=arm-linux-androideabi export AR=$target_host-ar export CMAKE_AR=$target_host-ar export AS=$target_host-clang export CC=$target_host-clang export CXX=$target_host-clang++ export LD=$target_host-ld export STRIP=$target_host-strip export SYSROOT=`pwd`/android-toolchain/sysroot # Tell configure what flags Android requires. export CFLAGS="-fPIE -fPIC" export LDFLAGS="-pie" #------------------------# #---- Build protobuf ----# #------------------------# cd ../externals/protobuf/ && export PROTOBUF_INC_PATH=`pwd`/src && ./autogen.sh cd $BUILD_DIR mkdir protobuf && cd protobuf # make sure that the protoc executable you use has the same version as the protobuf source code # build protobuf for host to get the executable protoc mkdir host && cd host env -i PATH=$PATH ../../../externals/protobuf/configure --host=x86_64-pc-linux-gnu make -j$(nproc) export PROTOBUF_PROTOC_PATH=`pwd`/src cd .. # build protobuf for target with protoc from host ../../externals/protobuf/configure --host=$target_host --enable-static --disable-shared --with-protoc=./host/src/protoc LDFLAGS="$LDFLAGS -llog" make -j$(nproc) export PROTOBUF_PATH=`pwd`/src cd .. #-------------------# #---- Get boost ----# #-------------------# mkdir boost && cd boost export BOOST_VERSION=1.68.0 export BOOST_VERSION_UNDERSCORE="${BOOST_VERSION//./_}" wget https://dl.bintray.com/boostorg/release/$BOOST_VERSION/source/boost_$BOOST_VERSION_UNDERSCORE.tar.gz tar -xf boost_$BOOST_VERSION_UNDERSCORE.tar.gz export BOOST_ROOT=`pwd`/boost_$BOOST_VERSION_UNDERSCORE cd .. #------------------------# #---- Build valhalla ----# #------------------------# mkdir valhalla && cd valhalla export VALHALLA_DIR=absolute/path/to/valhalla/directory export VALHALLA_BUILD_DIR=`pwd` cmake \ -DCMAKE_BUILD_TYPE=Release -DENABLE_TOOLS=Off -DENABLE_DATA_TOOLS=Off -DENABLE_PYTHON_BINDINGS=Off -DENABLE_NODE_BINDINGS=Off -DENABLE_HTTP=Off -DENABLE_SERVICES=Off \ -DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DANDROID_PLATFORM=android-28 \ -DProtobuf_INCLUDE_DIR=$PROTOBUF_INC_PATH -DProtobuf_LIBRARIES=$PROTOBUF_PATH \ -DProtobuf_PROTOC_EXECUTABLE=$PROTOBUF_PROTOC_PATH/protoc \ -DBoost_INCLUDE_DIR=$BOOST_ROOT \ -DCMAKE_CXX_FLAGS=-isystem\ $BOOST_ROOT\ -isystem\ /$PROTOBUF_INC_PATH \ $VALHALLA_DIR/. make -j$(nproc) cd ..
how did you get protobuf and place it? i absolutely have zero knowledge on it