build: android-custom-ndk: update the script for newer API

This commit is contained in:
Daniel Pocock
2021-10-30 13:09:59 +02:00
parent 6a90c6ee2f
commit 745d462464
5 changed files with 185 additions and 46 deletions

77
README_Android.txt Normal file
View File

@@ -0,0 +1,77 @@
About
-----
Android is a Linux-like operating system. It uses the Linux kernel
and the bionic C library rather than the more common glibc.
Android comes with an SDK for Java, the primary language used in
app development and a Native Development Kit (NDK) for low-level
languages such as C++.
History
-------
Android support was first added to the stack in 2013 by Daniel Pocock
The Android build was updated in 2021 for API level 21 with
support from Mobile Insight.
SDK and NDK evolution
---------------------
The original SDK was based on the Eclipse IDE. Since 2014, the SDK
is Android Studio, based on JetBrains' IntelliJ.
In the early days of the NDK, developers figured out how to integrate
their build systems with the NDK toolchains manually using scripts.
This was the approach used in the original reSIProcate Android effort.
Specifically, the build/android-custom-ndk script was created as a
wrapper around autotools. More recently, Google has included this
strategy in their documentation:
https://developer.android.com/ndk/guides/other_build_systems#autoconf
In 2016, Android Studio 2.2 introduced support for CMake with the NDK.
Using CMake is not mandatory. The SDK/NDK bundles a specific version
of CMake and if reSIProcate changes to CMake, it will be helpful
to ensure the versions are compatible.
https://android-developers.googleblog.com/2016/11/make-and-ndk-build-support-in-android.html
The original NDK was using the GCC toolchain for cross-compiling.
In around 2016, GCC was deprecated in favor of the CLang toolchain.
The list of CPU architectures supported by Android has evolved over time:
https://developer.android.com/ndk/guides/abis
Building for Android
--------------------
On a Linux host, install the SDK and NDK using the usual procedure.
Clone the reSIProcate project.
The first time you build reSIProcate, you will also need to
download and build OpenSSL for Android. Simply add the environment
variable BUILD_OPENSSL=1 to the front of your command line.
It is necessary to set the NDK_HOME environment variable through
the command line or your shell profile.
Here is an example:
BUILD_OPENSSL=1 \
NDK_HOME=${HOME}/Android/Sdk/ndk/23.1.7779620 \
build/android-custom-ndk
The binaries from both OpenSSL and reSIProcate are placed
in the directory ${HOME}/ndk-prebuilt
When you configure the logger in your code, we recommended you
enable the AndroidLogger from rutil/AndroidLogger.hxx
and then all the reSIProcate log output will be passed through
the Android logging system.
See the android-demo-message application for an example showing
how to integrate the libraries into your own app.
https://github.com/resiprocate/android-demo-message

View File

@@ -3,7 +3,8 @@ set -e
# The Android API level from
# https://developer.android.com/studio/releases/platforms
PLATFORM=android-9
API_LEVEL=21
PLATFORM=android-${API_LEVEL}
# We only build a subset of the reSIProcate stack for Android.
# Here we specify which directories we attempt to build.
@@ -35,15 +36,21 @@ then
exit 1
fi
# you need OpenSSL from
# https://github.com/guardianproject/openssl-android.git
# clone it and run "prebuilt/deploy-prebuilt.sh" or just "ndk-build"
export OPENSSL_HOME=${HOME}/ws/openssl/openssl-android
# This is where we download OpenSSL to be compiled
# with the same toolchain.
OPENSSL_URL=https://www.openssl.org/source/openssl-1.1.1l.tar.gz
if [ ! -d ${OPENSSL_HOME} ];
if [ "${BUILD_OPENSSL}" == 1 ];
then
echo "Can't find ${OPENSSL_HOME}"
exit 1
OPENSSL_PREBUILT=`mktemp -d`
RESIP_BUILD_DIR="`pwd`"
cd ${OPENSSL_PREBUILT}
wget ${OPENSSL_URL}
OPENSSL_TGZ=`echo ${OPENSSL_URL} | tr '/' '\n' | tail -1`
tar xzf ${OPENSSL_TGZ}
OPENSSL_DIR_BASE=`basename ${OPENSSL_TGZ} .tar.gz`
OPENSSL_DIR=`readlink -f ${OPENSSL_DIR_BASE}`
cd "${RESIP_BUILD_DIR}"
fi
# Determine how many CPU cores are available for parallel compilation
@@ -80,46 +87,104 @@ do
source ${MOD_SRC}
# We use the script provided by the NDK to make a standalone toolchain
# in the temporary location
# A standalone toolchain combines the following:
# - the compiler for the target CPU
# - the headers and system libraries for the target Android API level
# https://developer.android.com/ndk/guides/standalone_toolchain
MY_NDK=`mktemp -d`
echo "Creating a toolchain in ${MY_NDK}"
${NDK_HOME}/build/tools/make-standalone-toolchain.sh --platform=${PLATFORM} \
--install-dir=${MY_NDK} --system=linux-x86_64 --arch=${MOD_ARCH}
OPENSSL_NDK_DIST=${NDK_DIST}/openssl/${MOD_NAME}
# Build OpenSSL for this architecture if requested to do so
if [ -z "${OPENSSL_DIR}" ];
then
OPENSSL_HEADER_CHECK=${OPENSSL_NDK_DIST}/include/openssl/opensslv.h
if [ ! -e ${OPENSSL_HEADER_CHECK} ];
then
echo "Could not find ${OPENSSL_HEADER_CHECK} - please try setting BUILD_OPENSSL=1"
exit 1
fi
else
export OPENSSL_INSTALL=${OPENSSL_DIR}/../install-${MOD_ARCH}
(
cd ${OPENSSL_DIR}
export ANDROID_NDK_HOME=${NDK_HOME}
PATH=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$PATH
if [ ${MOD_ARCH} == x86 ];
then
./Configure android-${MOD_ARCH} -D__ANDROID_API__=${API_LEVEL} 386
else
./Configure android-${MOD_ARCH} -D__ANDROID_API__=${API_LEVEL}
fi
# make sure builds for other architectures are cleaned up before
# we begin
make clean
make -j${PAR}
make -j${PAR} DESTDIR=${OPENSSL_INSTALL} install
mkdir -p ${OPENSSL_NDK_DIST}
# store a permanent copy for future use
cp -r ${OPENSSL_INSTALL}/usr/local/include ${OPENSSL_INSTALL}/usr/local/lib/* ${OPENSSL_NDK_DIST}
)
fi
# This is a target triplet, it is the argument to the --host parameter
# of GNU configure
# https://www.gnu.org/software/automake/manual/html_node/Cross_002dCompilation.html
# https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.70/html_node/Specifying-Target-Triplets.html
export CROSS_COMPILE
# and it is also the prefix added to the filenames of tools for that
# cross-compile.
export TOOLCHAIN_PREFIX=${CROSS_COMPILE}
# File locations for the toolchain we just built:
export SYSROOT=${MY_NDK}/sysroot
export PATH=${MY_NDK}/bin:$PATH
if [ $API_LEVEL -lt 20 ];
then
# and for GNU tools, CROSS_COMPILE is also the prefix added to the filenames of tools for that
# cross-compile.
#export TOOLCHAIN_PREFIX=${CROSS_COMPILE}
# Names of the tools we are using, configure reads these from
# the environment.
export CPP=${TOOLCHAIN_PREFIX}-cpp
export AR=${TOOLCHAIN_PREFIX}-ar
export AS=${TOOLCHAIN_PREFIX}-as
export NM=${TOOLCHAIN_PREFIX}-nm
export CC=${TOOLCHAIN_PREFIX}-gcc
export CXX=${TOOLCHAIN_PREFIX}-g++
export LD=${TOOLCHAIN_PREFIX}-ld
export RANLIB=${TOOLCHAIN_PREFIX}-ranlib
# We use the script provided by the NDK to make a standalone toolchain
# in the temporary location
# A standalone toolchain combines the following:
# - the compiler for the target CPU
# - the headers and system libraries for the target Android API level
# https://developer.android.com/ndk/guides/standalone_toolchain
MY_NDK=`mktemp -d`
echo "Creating a toolchain in ${MY_NDK}"
${NDK_HOME}/build/tools/make-standalone-toolchain.sh --platform=${PLATFORM} \
--install-dir=${MY_NDK} --system=linux-x86_64 --arch=${MOD_ARCH}
# File locations for the toolchain we just built:
export SYSROOT=${MY_NDK}/sysroot
export PATH=${MY_NDK}/bin:$PATH
# Names of the tools we are using, configure reads these from
# the environment.
export CPP=${TOOLCHAIN_PREFIX}-cpp
export AR=${TOOLCHAIN_PREFIX}-ar
export AS=${TOOLCHAIN_PREFIX}-as
export NM=${TOOLCHAIN_PREFIX}-nm
export CC=${TOOLCHAIN_PREFIX}-gcc
export CXX=${TOOLCHAIN_PREFIX}-g++
export LD=${TOOLCHAIN_PREFIX}-ld
export RANLIB=${TOOLCHAIN_PREFIX}-ranlib
CXX_STL="-lgnustl_shared"
else
# newer CLang build
# based on these instructions:
# https://developer.android.com/ndk/guides/other_build_systems#autoconf
export TOOLCHAIN=${NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64
export TARGET=${CROSS_COMPILE}
export SYSROOT=${MY_NDK}/sysroot
export AR=$TOOLCHAIN/bin/llvm-ar
export CC=$TOOLCHAIN/bin/$TARGET${API_LEVEL}-clang
export AS=$CC
export CXX=$TOOLCHAIN/bin/$TARGET${API_LEVEL}-clang++
export LD=$TOOLCHAIN/bin/ld
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
export STRIP=$TOOLCHAIN/bin/llvm-strip
CXX_STL="-lc++_shared"
fi
# Set *FLAGS for the build, once again, configure reads these from
# the environment.
export CPPFLAGS="${CPPFLAGS} -I${OPENSSL_HOME}/include"
export CPPFLAGS="${CPPFLAGS} -fPIC -I${OPENSSL_NDK_DIST}/include"
export CXXFLAGS="${CXXFLAGS} -Os"
export LDFLAGS="${LDFLAGS} -L${OPENSSL_HOME}/libs/${MOD_NAME}"
export LDFLAGS="${LDFLAGS} -L${OPENSSL_NDK_DIST} ${CXX_STL}"
autoreconf -fi
@@ -136,6 +201,11 @@ do
--with-ssl \
"$@"
# these need asio and boost headers
# reTurn can be modified to use C++11 std::bind and friends to
# reduce dependency on boost
# --with-return --with-recon
# We build the specified directories one by one.
for proj in $PROJECTS ;
do

View File

@@ -1,7 +0,0 @@
MOD_ARCH=arm
CROSS_COMPILE=arm-linux-androideabi
# for 16 bit Thumb-1 (default is 32 bit ARM)
CPPFLAGS="${CPPFLAGS} -mthumb"

View File

@@ -1,6 +1,6 @@
MOD_ARCH=arm
CROSS_COMPILE=arm-linux-androideabi
CROSS_COMPILE=armv7a-linux-androideabi
# for ARMv7
export CPPFLAGS="${CPPFLAGS} -march=armv7-a -mfloat-abi=softfp"

View File

@@ -140,8 +140,7 @@ AC_ARG_WITH(fmt,
AC_ARG_ENABLE(android,
[ --enable-android Enable Android build],
[AC_SUBST(LIBPTHREAD_LIBADD, "")
AC_SUBST(LIBLOG_LIBADD, "-llog")
AC_SUBST(LIBSTL_LIBADD, "-lgnustl_shared")],
AC_SUBST(LIBLOG_LIBADD, "-llog")],
[AC_SUBST(LIBPTHREAD_LIBADD, "-lpthread")
AC_SUBST(LIBLOG_LIBADD, "")
AC_SUBST(LIBSTL_LIBADD, "")])