# Build Sequoia for Android

Based on this [guide].

  [guide]: https://mozilla.github.io/firefox-browser-architecture/experiments/2017-09-21-rust-on-android.html

For building and using a plain rust project, its enough with following the guide,
but if they are native dependencies like openssl or Nettle as in the Sequoia case,
these dependencies need to be crossbuilt before starting the cargo build.

This instructions are tested for the host target `$HOST=armv7-linux-androideabi`
and using **Debian Squeeze**

0. Setup env to build using NDK and env
1. Setup rust for crossbuilding (follow guide above)
2. Download dependencies
3. Cross build OpenSSL for Android
4. Cross build Nettle and its dependencies (libgmp) for Android
5. Build Sequoia

### 0. ANDROID NDK Standalone toolchains

We need `$ANDROID_NDK` to be pointing to the [NDK standalone toolchain]

  [NDK standalone toolchain]: https://developer.android.com/ndk/guides/standalone_toolchain

```bash
ANDROID_NDK=$STANDALONE_NDK_PATH
export PATH=$PATH:ANDROID_NDK/bin
```

Now that we have the NDK setup, we need to setup and define our build environment:

```bash
mkdir -p /tmp/sequoia-build
export PREFIX=/tmp/sequoia-build
export BUILD_DIR=/tmp/sequoia-build
export HOST_ARCH=arm-linux-androideabi
```

### 1. Setup rust for crossbuilding

Follow this [guide] until:

  [guide]: https://mozilla.github.io/firefox-browser-architecture/experiments/2017-09-21-rust-on-android.html

```
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android
```

Now you have your env ready to cross build, we need to build Sequoia's dependencies.

### 2. Download dependencies

We need to download, OpenSSL, GMP and Nettle, for that we will use
the official download pages:

* Openssl: http://www.openssl.org/source/
* GMP: https://gmplib.org/
* Neetle: https://ftp.gnu.org/gnu/nettle/

Replace "X.Y.Z" with the latest version of each software package.

```bash
export OPENSSL_VERSION="X.Y.Z"
export GMP_VERSION="X.Y.Z"
export NETTLE_VERSION="X.Y.Z"
```

to get them:

```bash
wget -nc https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz
wget -nc https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz.asc
wget -nc https://gmplib.org/download/gmp/gmp-$GMP_VERSION.tar.bz2
wget -nc https://gmplib.org/download/gmp/gmp-$GMP_VERSION.tar.bz2.sig
wget -nc https://ftp.gnu.org/gnu/nettle/nettle-$NETTLE_VERSION.tar.gz
wget -nc https://ftp.gnu.org/gnu/nettle/nettle-$NETTLE_VERSION.tar.gz.sig
```


**Before using the downloaded files please check their integrity, if it fails
abort**


And then untar:

```bash
gpg --auto-key-locate --verify openssl-$OPENSSL_VERSION.tar.gz.asc openssl-$OPENSSL_VERSION.tar.gz
tar xvf openssl-$OPENSSL_VERSION.tar.gz
gpg --verify gmp-$GMP_VERSION.tar.bz2.sig gmp-$GMP_VERSION.tar.bz2
tar xvf gmp-$GMP_VERSION.tar.bz2
gpg --verify nettle-$NETTLE_VERSION.tar.gz.sig nettle-$NETTLE_VERSION.tar.gz
tar xvf nettle-$NETTLE_VERSION.tar.gz
```

### 3. CrossBuild OpenSSL for Android

Note: These instructions are for OpenSSL 1.1.1 series, not compatible with
previous series.

```bash
cd openssl-$OPENSSL_VERSION && \
./Configure android-arm --prefix=$PREFIX && \
make && make install && cd ..
```

Now we need to set ARMV7_LINUX_ANDROIDEABI_OPENSSL_LIB_DIR and
ARMV7_LINUX_ANDROIDEABI_OPENSSL_INCLUDE_DIR to
make rust native-tls find the right openssl.

```bash
ARMV7_LINUX_ANDROIDEABI_OPENSSL_LIB_DIR="$PREFIX/lib"
ARMV7_LINUX_ANDROIDEABI_OPENSSL_INCLUDE_DIR="$PREFIX/include"
```

### 4. Crossbuild Nettle for Android

First we need to build libgmp:

```bash
cd gmp-${GMP_VERSION} && \
CFLAGS="-fPIE -fPIC" \
LDFLAGS="-pie -march=armv7-a -Wl,--fix-cortex-a8" \
AR="${HOST_ARCH}-ar" \
AS="${HOST_ARCH}-clang" \
CC="${HOST_ARCH}-clang" \
CXX="${HOST_ARCH}-clang++" \
LD="${HOST_ARCH}-ld" \
PKG_CONFIG_ALLOW_CROSS=1 \
PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig \
STRIP="${HOST_ARCH}-strip" ./configure --host=${HOST_ARCH} --prefix=${PREFIX} && \
make && make install && cd ..
```

Now is Nettle turn:

```bash
cd nettle-${NETTLE_VERSION} && \
CFLAGS="-fPIE -fPIC" \
LDFLAGS="-pie -march=armv7-a -Wl,--fix-cortex-a8" \
AR="${HOST_ARCH}-ar" \
AS="${HOST_ARCH}-clang" \
CC="${HOST_ARCH}-clang" \
CXX="${HOST_ARCH}-clang++" \
LD="${HOST_ARCH}-ld" \
PKG_CONFIG_ALLOW_CROSS=1 \
PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig \
STRIP="${HOST_ARCH}-strip" ./configure --host=${HOST_ARCH}  --prefix=${PREFIX} \
--with-lib-path=${PREFIX}/lib \
--with-include-path=${PREFIX}/include && \
make && make install && cd ..
```

### 5. Build Sequoia

To build Sequoia for android it is needed to use sqlite as amalgam as the NDK
does not provide access to the system sqlite.

First get the source code

```bash
git clone https://gitlab.com/sequoia-pgp/sequoia.git
```

and then build

```
 cd sequoia && \
 LD_LIBRARY_PATH=$PREFIX/lib/ PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig \
 PKG_CONFIG_ALLOW_CROSS=1 ARMV7_LINUX_ANDROIDEABI_OPENSSL_LIB_DIR="$PREFIX/lib" \
 ARMV7_LINUX_ANDROIDEABI_OPENSSL_INCLUDE_DIR="$PREFIX/include" \
 ARMV7_LINUX_ANDROIDEABI_OPENSSL_DIR="$PREFIX/bin" \
 CARGO_TARGET_DIR=$BUILD_DIR CARGO_FLAGS="--target armv7-linux-androideabi" \
 make build PYTHON=disable
```

Once we have it build, we only need to link sequoia-ffi.so to the jni libs
paths for example

```bash
ln -s $CARGO_TARGET_DIR/armv7-linux-androideabi/debug/libsequoia_ffi.so \
$ANDROID_PROJECT_PATH/app/src/main/jniLibs/armeabi/libsequoia_ffi.so

```
