Skip to content

Commit 0e143e5

Browse files
committed
feat(nix): nix-shell with android setup and ci checks for it
Part of an implementation example for android support, this offers a nix shell that helps with the setup and exports some checks that try to build the project for android, these checks will fail until the next commit adds the build.rs changes.
1 parent 9975909 commit 0e143e5

2 files changed

Lines changed: 157 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,28 @@ jobs:
211211
- name: Build and test
212212
run: cargo test -vv
213213

214+
215+
android-nix-cross-check:
216+
name: Cross-Compile (${{ matrix.check }}) building using nix
217+
runs-on: ubuntu-latest
218+
strategy:
219+
fail-fast: false
220+
matrix:
221+
check:
222+
- android-aarch64
223+
- android-armv7
224+
- android-x86_64
225+
steps:
226+
- uses: actions/checkout@v4
227+
228+
- uses: cachix/install-nix-action@v27
229+
with:
230+
extra_nix_config: |
231+
accept-flake-config = true
232+
233+
- name: Build check
234+
run: nix build .#checks.x86_64-linux.${{ matrix.check }} -L
235+
214236
fuzz-corpus:
215237
name: Verify Fuzz Corpus
216238
runs-on: ubuntu-latest

flake.nix

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
let
1616
pkgs = import nixpkgs {
1717
inherit system;
18+
config.android_sdk.accept_license = true;
19+
config.allowUnfree = true;
1820
};
1921

2022
rustVersion = "1.71.0";
@@ -35,6 +37,98 @@
3537
cargo = rustBuildToolchainNightly;
3638
rustc = rustBuildToolchainNightly;
3739
};
40+
androidComposition = pkgs.androidenv.composeAndroidPackages {
41+
platformVersions = [ "34" ];
42+
ndkVersions = [ "27.2.12479018" ];
43+
includeNDK = true;
44+
};
45+
androidSdk = androidComposition.androidsdk;
46+
androidNdk = "${androidSdk}/libexec/android-sdk/ndk/27.2.12479018";
47+
48+
rustAndroidToolchain = fenix.packages.${system}.combine [
49+
rustToolchain.rustc
50+
rustToolchain.cargo
51+
rustToolchain.rust-src
52+
rustToolchain.rust-std
53+
(fenix.packages.${system}.targets.aarch64-linux-android.fromToolchainName {
54+
name = rustVersion;
55+
sha256 = "sha256-ks0nMEGGXKrHnfv4Fku+vhQ7gx76ruv6Ij4fKZR3l78=";
56+
}).rust-std
57+
(fenix.packages.${system}.targets.armv7-linux-androideabi.fromToolchainName {
58+
name = rustVersion;
59+
sha256 = "sha256-ks0nMEGGXKrHnfv4Fku+vhQ7gx76ruv6Ij4fKZR3l78=";
60+
}).rust-std
61+
(fenix.packages.${system}.targets.x86_64-linux-android.fromToolchainName {
62+
name = rustVersion;
63+
sha256 = "sha256-ks0nMEGGXKrHnfv4Fku+vhQ7gx76ruv6Ij4fKZR3l78=";
64+
}).rust-std
65+
];
66+
67+
# -- Source filtering --
68+
src = pkgs.lib.cleanSourceWith {
69+
src = self;
70+
filter = path: type:
71+
!(builtins.any (suffix: pkgs.lib.hasSuffix suffix path) [
72+
"/target"
73+
"/.git"
74+
"/result"
75+
]);
76+
};
77+
78+
# -- Stable Rust for checks (MSRV is too old for some vendored crate manifests) --
79+
rustStable = fenix.packages.${system}.stable;
80+
mkAndroidCheck = { name, rustTarget }:
81+
let
82+
androidStableToolchain = fenix.packages.${system}.combine [
83+
rustStable.rustc
84+
rustStable.cargo
85+
rustStable.rust-src
86+
rustStable.rust-std
87+
fenix.packages.${system}.targets.${rustTarget}.stable.rust-std
88+
];
89+
androidRustPlatform = pkgs.makeRustPlatform {
90+
cargo = androidStableToolchain;
91+
rustc = androidStableToolchain;
92+
};
93+
in
94+
androidRustPlatform.buildRustPackage {
95+
pname = "rust-bitcoinkernel-android-${name}";
96+
version = "0.2.0";
97+
inherit src;
98+
99+
cargoLock.lockFile = self + "/Cargo-recent.lock";
100+
101+
nativeBuildInputs = [
102+
pkgs.cmake
103+
pkgs.pkg-config
104+
pkgs.python3
105+
androidSdk
106+
];
107+
108+
buildInputs = [
109+
pkgs.boost.dev
110+
];
111+
112+
LIBCLANG_PATH = "${pkgs.llvmPackages.clang-unwrapped.lib}/lib/";
113+
ANDROID_HOME = "${androidSdk}/libexec/android-sdk";
114+
ANDROID_NDK_HOME = androidNdk;
115+
ANDROID_NDK_ROOT = androidNdk;
116+
CARGO_BUILD_TARGET = rustTarget;
117+
118+
buildPhase = ''
119+
runHook preBuild
120+
cargo build --target ${rustTarget} --release -p libbitcoinkernel-sys
121+
runHook postBuild
122+
'';
123+
doCheck = false;
124+
125+
installPhase = ''
126+
touch $out
127+
'';
128+
129+
dontFixup = true;
130+
};
131+
38132
rustfilt = rustPlatformNightly.buildRustPackage rec {
39133
pname = "rustfilt";
40134
version = "0.2.1";
@@ -77,6 +171,47 @@
77171
pkgs.gcc.cc.lib
78172
];
79173
};
174+
175+
# Android development shell. Enter with:
176+
# nix develop .#android
177+
# This gives you a shell with the Android NDK, Rust toolchains
178+
# (with Android targets), cmake, and boost — everything needed to
179+
# run: cargo build --target aarch64-linux-android -p libbitcoinkernel-sys
180+
devShells.android = pkgs.mkShell {
181+
packages = [
182+
rustAndroidToolchain
183+
184+
pkgs.cmake
185+
pkgs.boost.dev
186+
androidSdk
187+
];
188+
189+
LIBCLANG_PATH = "${pkgs.llvmPackages.clang-unwrapped.lib}/lib/";
190+
ANDROID_HOME = "${androidSdk}/libexec/android-sdk";
191+
ANDROID_NDK_HOME = androidNdk;
192+
ANDROID_NDK_ROOT = androidNdk;
193+
};
194+
195+
# Verify Android cross-compilation. Run with:
196+
# nix build .#checks.x86_64-linux.android-aarch64 -L
197+
# nix build .#checks.x86_64-linux.android-armv7 -L
198+
# nix build .#checks.x86_64-linux.android-x86_64 -L
199+
checks = {
200+
android-aarch64 = mkAndroidCheck {
201+
name = "aarch64";
202+
rustTarget = "aarch64-linux-android";
203+
};
204+
205+
android-armv7 = mkAndroidCheck {
206+
name = "armv7";
207+
rustTarget = "armv7-linux-androideabi";
208+
};
209+
210+
android-x86_64 = mkAndroidCheck {
211+
name = "x86_64";
212+
rustTarget = "x86_64-linux-android";
213+
};
214+
};
80215
}
81216
);
82217
}

0 commit comments

Comments
 (0)