Skip to content

Feat: Android support#158

Open
jaoleal wants to merge 3 commits into
sedited:masterfrom
jaoleal:android_support
Open

Feat: Android support#158
jaoleal wants to merge 3 commits into
sedited:masterfrom
jaoleal:android_support

Conversation

@jaoleal
Copy link
Copy Markdown
Contributor

@jaoleal jaoleal commented Apr 10, 2026

This pr contain 3 commits:

  1. an old version of Add MSRV Cargo-minimal.lock and Cargo-recent.lock files #150 to make CI work again flawlessly.
  2. A patch to the projects flake adding a nix-shell that give us the necessary setup for the android build, which includes the android toolchain and some environment variables. The second commit also introduces a new job on the CI that executes the building for android.
  3. Android building instructions for build.rs

This is just a PoC, the main commit is the third one and the CI job containing the android building at that point should run fine.
For more context read #156

@jaoleal jaoleal mentioned this pull request Apr 10, 2026
@sedited
Copy link
Copy Markdown
Owner

sedited commented Apr 23, 2026

This looks nice, can you rebase this?

@jaoleal
Copy link
Copy Markdown
Contributor Author

jaoleal commented Apr 30, 2026

Changelog:

@jaoleal jaoleal force-pushed the android_support branch 6 times, most recently from a2c959f to 0f3252f Compare May 6, 2026 20:07
@jaoleal jaoleal changed the title POC: Android support Feat: Android support May 6, 2026
@jaoleal jaoleal marked this pull request as ready for review May 6, 2026 20:08
@jaoleal
Copy link
Copy Markdown
Contributor Author

jaoleal commented May 6, 2026

I reduced a lot the code and i think this is the concise version to support android

@alexanderwiederin
Copy link
Copy Markdown
Collaborator

alexanderwiederin commented May 7, 2026

I don't think android is a supported target for libbitcoinkernel. Doesn't this require upstream work on bitcoin core first?

Copy link
Copy Markdown
Collaborator

@alexanderwiederin alexanderwiederin left a comment

Choose a reason for hiding this comment

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

From what I understand the ubuntu boost packages don't ship with the cmake config that core needs when cross-compiling.

Am I right that you got it working on nix locally? If so, can we stick with with only supporting the nix build for android?

Comment thread flake.nix Outdated
Comment thread flake.nix Outdated
@jaoleal
Copy link
Copy Markdown
Contributor Author

jaoleal commented May 7, 2026

Am I right that you got it working on nix locally? If so, can we stick with with only supporting the nix build for android?

Yes, i worked all this on nix but Im not sure about leaving android building exclusively for nix, this would make it a direct dependency of the project and its not something really special that only nix can do. Besides the dependency problem, nix can drift versions because of nixpkgs releases and that can raise problems only by itself.

Therefore, i still would like for CI to keep the runner as ubuntu. Its easier for the general developer audience to replicate the build on their machine if they need

Edit: see the comment below

@jaoleal
Copy link
Copy Markdown
Contributor Author

jaoleal commented May 7, 2026

Correction, I changed my mind... The idea is that the build.rs file is already bloated because of the android support additions, adding support for ubuntu bloated it even more... It looks like leaving to nix to cross-compile to android is actually a good choice, the changes stay minimal on build.rs side and it have broader support running on linux and macos machines... Ill make sure to document that somewhere and state how to make the android build.

@jaoleal jaoleal force-pushed the android_support branch from 0f3252f to 49309b8 Compare May 7, 2026 23:43
This commit presents the minimal work needed for this crate to be
able to be compiled for android, this is minimal to avoid bloating
too much the build process, which would make it hard to review and
maintain. The rest of the work will be done on nix side, which
provides better ergonomics for such job.
@jaoleal jaoleal force-pushed the android_support branch 3 times, most recently from e9e6806 to 479401e Compare May 8, 2026 00:21
jaoleal added 2 commits May 7, 2026 21:22
This commit presents the rest of the work to provide android
builds, the packaging and compiling is done trough nix for simplicity
@jaoleal jaoleal force-pushed the android_support branch from 479401e to 30f44a8 Compare May 8, 2026 00:24
@jaoleal
Copy link
Copy Markdown
Contributor Author

jaoleal commented May 8, 2026

Okay the android build being exclusive for nix made things easier for this PR, the changes on build.rs are minimal... I included some inline doc comments so the reviewer can follow why each line were added.

I added a section on the readme explaining the android build but its not that explanatory in a level that one can learn how to build this lib to android, do you guys think thats needed ?

I can extend the docs to include instructions for one to reproduce it on a downstream build.rs, just tell me where to put it.
AFAIK is trivial for those using Kotlin, as mandacaru is using, to pull an already compiled shared object during build time. Thats what ill do on floresta-nix for mandacaru, ideally the CI would also offer the compiled objects too for those who might need it.

Copy link
Copy Markdown
Collaborator

@alexanderwiederin alexanderwiederin left a comment

Choose a reason for hiding this comment

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

Great to see this working.

If we land the hand-written bindings PR (#163) first, the changes in build.rs should become simpler. I would suggest we wait for it.

Comment on lines +82 to +86
assert!(
Path::new(&toolchain_file).exists(),
"Android NDK toolchain file not found at {toolchain_file}. \
Check that ANDROID_NDK_HOME points to a valid NDK installation"
);
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.

I think asserts are for faults in logic, not environment variables. I think a !path.exists() { panic!(...) } or .expect() would read more naturally here.

Comment on lines +99 to +100
.arg(format!("-DCMAKE_ANDROID_ARCH_ABI={abi}"))
.arg(format!("-DCMAKE_SYSTEM_VERSION={api_level}"))
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.

Do we really have to pass these in a second time after lines 96 and 97?

Comment thread flake.nix
};
androidComposition = androidPkgs.androidenv.composeAndroidPackages {
platformVersions = [ "34" ];
ndkVersions = [ "27.2.12479018" ];
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.

27.2.12479018 is duplicated on line 94. I would suggest we make it a variable.

Comment thread flake.nix
Comment on lines +105 to +106
name = rustVersion;
sha256 = "sha256-ks0nMEGGXKrHnfv4Fku+vhQ7gx76ruv6Ij4fKZR3l78=";
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.

The sha256 here is already defined at the top of the flake as part of rustToolchain. Extract it into a rustSha256 variable alongside rustVersion and reference it in both places. Otherwise a toolchain bump requires updating two identical hashes.

Comment thread flake.nix
config.allowUnfree = true;
};
androidComposition = androidPkgs.androidenv.composeAndroidPackages {
platformVersions = [ "34" ];
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.

Can we add a comment above this?

# platformVersions is the SDK tooling version, not the minimum API level.
# The NDK target floor is set via ANDROID_API_LEVEL in build.rs (default 24).

Comment thread flake.nix
Comment on lines +151 to +153
android-aarch64 = mkAndroidPackage "aarch64-linux-android";
android-armv7 = mkAndroidPackage "armv7-linux-androideabi";
android-x86_64 = mkAndroidPackage "x86_64-linux-android";
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.

in build.rs, the android_abi() function handles four targets, but here only three are exposed. Is that intentional?

Comment thread .github/workflows/ci.yml
name: Cross-Compile for Android (${{ matrix.package }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
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.

good call!

Comment thread README.md
Android cross-compilation requires [Nix](https://nixos.org/).

Nix package outputs bundle the exact NDK version, Rust toolchains with Android
targets, Boost, and cmake in a single reproducible build drying out the support
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.

what do you mean "drying" out the support?

Comment thread README.md
cargo b
```

### Android Cross-Compilation
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.

Worth adding a note that the output targets Android API 24+ (Nougat) minimum, so people know the minimum Android version their app must support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants