# Cross compiling bodo\_connect
Follow the guide below to manually install all tools and libraries to build bodo\_connect for android
with statically linked openssl.
At the end of this guid there's a section for a more simple docker build.
## OpenSSL
OpenSSL on termux is strange, I tried using dynamic linking but without success. I personally
prefer statically linking openssl for bodo\_connect. The binary is a little bigger, but the hassle
is way smaller.
We need to get the openssl sources, then cross-compile the libraries to be statically linked to
the executable.
### Get sources
Get a stable version of openssl
```sh
git clone https://github.com/openssl/openssl --depth 1 --branch $OPENSSL_VERSION
cd openssl
```
### Configure and compile with android ndk
1. Firstly install android-ndk, with sdkmanager (`yay -S sdkmanager`) or from aur (`yay -S android-ndk`)
2. Set environment variables for ndk to work
```sh
export ANDROID_NDK_ROOT=/opt/android-ndk
export PATH="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH"
```
3. Configure android architecture and [API level](https://apilevels.com/).
*Available android architectures are: `android-arm`, `android-arm64`, `android-mips`,
`android-mip64`, `android-x86`, `android-x86_64` and `android-riscv64`.*
```sh
./Configure $OPENSSL_ANDROID_ARCH
you want to use the latest.
```
4. Compile
```sh
make
```
## Prepare rust toolchain
We need to add the needed android target
```sh
# example CARGO_ANDROID_TRIPLE=aarch64-linux-android
rustup toolchain install nightly
rustup target add $CARGO_ANDROID_TRIPLE
```
Check that the linker and ar executables are set in the file `.cargo/config.toml`. Example:
```toml
[target.aarch64-linux-android]
linker = "aarch64-linux-android34-clang"
```
## Compile
We firstly need to set a bunch of env variables to make sure that cargo statically builds openssl and
finds openssl libraries and headers.
```sh
export OPENSSL_LIB_DIR=$PWD/openssl
export OPENSSL_INCLUDE_DIR=$PWD/openssl/include/
export OPENSSL_STATIC=1
```
The we can finally compile
```sh
cargo build --release --target $CARGO_ANDROID_TRIPLE
```
## Extra: environment variables example
```sh
export OPENSSL_VERSION=openssl-3.3.2
export OPENSSL_ANDROID_ARCH=android-arm64
export OPENSSL_ANDROID_API=34
export ANDROID_NDK_ROOT=/opt/android-ndk
export PATH="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH"
export OPENSSL_INCLUDE_DIR=$PWD/openssl/include
export OPENSSL_LIB_DIR=$PWD/openssl/
export OPENSSL_STATIC=1
export CARGO_ANDROID_TRIPLE=aarch64-linux-android
export MAKEFLAGS=-j$(nproc)
```
# Docker
This method uses the above steps to create a build environment capable of building every rust
project that need a statically linked openssl and must have android support.
```Dockerfile
# ...
ARG AUR_PKGS=android-ndk
# ...
ARG OPENSSL_ARCH=android-arm64
ARG OPENSSL_ANDROID_API=
ARG OPENSSL_VERSION=openssl-3.3.2
ARG CARGO_BUILD_TARGET=aarch64-linux-android
# ...
```
Copy the `Dockerfile.empty` file into `Dockerfile`, then edit the file setting the desired
options. Here's an explanation of the options:
- `AUR_PKGS`: pkgs to get and build from AUR before compiling. Usually it's some cross-compile like
`aarch64-none-linux-gnu-gcc-12.3-bin`
- `OPENSSL_ARCH`: openssl architecture. For generic linux usage use linux-generic32 and
linux-generic64 If using android choose the right one from this list (more details
[here](https://github.com/openssl/openssl/blob/master/NOTES-ANDROID.md)):
- `android-arm`
- `android-arm64`
- `android-mips`
- `android-mip64`
- `android-x86`
- `android-x86_64`
- `android-riscv64`
- `OPENSSL_ANDROID_API`: (optional) android sdk/api version, refer to [this](https://apilevels.com) site
to find the right one.
*Note that if you leave it blank it will be used the latest available one for openssl*
- `OPENSSL_VERSION`: which branch of the [openssl repo](https://github.com/openssl/openssl) to pull from.
- `OPENSSL_CONFIGURE_EXTRA`: (optional) will be append after `./Configure`
- `CARGO_BUILD_TARGET`: default cargo target, can be overrided using `cargo --target $TARGET_TRIPLE`. Keep
in mind that if you do, you will need to install that target using `rustup target add $TARGET_TRIPLE`.