Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions ANDROID.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Android Cross-Compilation (manual)

This document describes how to cross-compile `rust-bitcoinkernel` for Android
without Nix. If you can use Nix, prefer the `nix build` outputs described in
the [README](README.md#android-cross-compilation) — they pin the NDK, Rust
toolchains, Boost, and cmake for you.

## Prerequisites

Android NDK (r27+ recommended), cmake, and Boost headers installed on the

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Android NDK (r27+ recommended), cmake, and Boost headers installed on the
Android NDK (tested with r27.3), cmake, and Boost headers installed on the

host.

Install the Rust target for the architecture you want:

```bash
rustup target add aarch64-linux-android # 64-bit ARM
rustup target add armv7-linux-androideabi # 32-bit ARM
rustup target add x86_64-linux-android # x86_64 emulator
```

## Environment

The NDK toolchain must be on `PATH` so cmake can find the compilers and
`llvm-ar`. Boost headers must be discoverable by cmake — either set
`CMAKE_PREFIX_PATH` or symlink them into the NDK sysroot:

```bash
export ANDROID_NDK_HOME=/path/to/android-ndk

# Detect host platform
NDK_HOST="linux-x86_64" # or "darwin-x86_64" on macOS

# Put NDK clang and llvm-ar on PATH
export PATH="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/$NDK_HOST/bin:$PATH"

# Option A: point cmake at your Boost installation
export CMAKE_PREFIX_PATH=/usr/lib/x86_64-linux-gnu/cmake

# Option B: symlink Boost headers into the NDK sysroot
ln -sf /usr/include/boost \
"$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/$NDK_HOST/sysroot/usr/include/boost"
```
Comment on lines +21 to +42

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about?

Environment

ANDROID_NDK_HOME selects the NDK that the build uses. If you have more than on NDK installed - Android Studio keeps several - make sure the PATH entry below points at the same one, or cmake and the linker will silently use different toolchains.

export ANDROID_NDK_HOME=/path/to/android-ndk
 
NDK_HOST="linux-x86_64"   # or "darwin-x86_64" on macOS
 
export PATH="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/$NDK_HOST/bin:$PATH"

Boost

cmake has to find the Boost package, and the NDK compiler has to find the
headers. For a distro-installed Boost, with headers in /usr/include/boost,
that takes two steps:

export CMAKE_PREFIX_PATH=/usr/lib/x86_64-linux-gnu/cmake   # Debian/Ubuntu
 
ln -sfn /usr/include/boost \
  "$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/$NDK_HOST/sysroot/usr/include/boost"

Which of the two options (A or B) did you take? Neither original option worked alone for Debian/Ubuntu for me.

Without CMAKE_PREFIX_PATH, cmake fails at configure. Without the symlink,
configure succeeds and the build fails later with
'boost/multi_index/hashed_index.hpp' file not found.

If Boost is installed under its own prefix (a source build, or Homebrew on
macOS), pointing CMAKE_PREFIX_PATH at that prefix may be enough on its own,
since the headers are then outside the system include directories. If the
build still reports a missing Boost header, add the symlink as well.


Which original option (A or B) did you take? Neither original option worked alone for me on Debian/Ubuntu.


## Building

Build the `-sys` crate (the static `libbitcoinkernel.a`). The NDK cmake
toolchain file handles cross-compiler selection, so no extra `CC` or linker
variables are needed for this step:

```bash
cargo build -p libbitcoinkernel-sys --target aarch64-linux-android --release
```

To build the higher-level `bitcoinkernel` crate or run tests, Cargo needs the
NDK clang as the linker. Set the appropriate `CARGO_TARGET_*_LINKER` variable:

```bash
export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android24-clang
cargo build --target aarch64-linux-android
```

The linker binary names for each target are:

| Target | Linker |
| ------------------------- | ---------------------------------- |
| `aarch64-linux-android` | `aarch64-linux-android24-clang` |
| `armv7-linux-androideabi` | `armv7a-linux-androideabi24-clang` |
| `x86_64-linux-android` | `x86_64-linux-android24-clang` |

## API level

Replace `24` in the linker name with a higher API level if needed.
`ANDROID_API_LEVEL` defaults to 24 (Nougat) and can be overridden:

```bash
export ANDROID_API_LEVEL=28
```
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ cargo b

### Android Cross-Compilation

Android cross-compilation requires [Nix](https://nixos.org/).
The recommended way to cross-compile for Android is with
[Nix](https://nixos.org/).

Nix handles the exact NDK version, Rust toolchains, Boost, and cmake
automatically, giving you a reproducible build environment with no manual setup.
Expand All @@ -51,6 +52,9 @@ The resulting libraries and headers are placed in `result/lib/` and `result/incl

Output targets Android API 24+ (Nougat) minimum.

If you cannot use Nix, see [ANDROID.md](ANDROID.md) for instructions on
setting up the NDK toolchain and building by hand.

## MSRV (Minimum Supported Rust Version)

The minimum supported Rust version is 1.71. Users on rustc older than
Expand Down
Loading