Skip to content

Commit e6af0a8

Browse files
committed
feat: add testing environment for android outputs
This commit introduces preparation for testing in both Nix and CI. Testing android outputs is restricted to x86_64-linux machines for simplicity. QEMU user-mode emulation is configured as the Cargo test runner for cross-compiled Android targets.
1 parent f05ecca commit e6af0a8

1 file changed

Lines changed: 47 additions & 9 deletions

File tree

flake.nix

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,20 @@
111111
androidSdk = androidComposition.androidsdk;
112112
androidNdk = "${androidSdk}/libexec/android-sdk/ndk/${ndkVersion}";
113113

114+
runTests = system == "x86_64-linux";
115+
116+
# x86_64-linux-android is excluded from tests: Rust 1.71's
117+
# compiler_builtins lacks the f128 routines (__eqtf2, __multf3, …)
118+
# that bionic's static libc.a requires on x86_64.
119+
testableTargets = [
120+
"aarch64-linux-android"
121+
"armv7-linux-androideabi"
122+
];
123+
114124
mkAndroidPackage =
115125
rustTarget:
116126
let
127+
canTest = runTests && builtins.elem rustTarget testableTargets;
117128
rustTargetToolchain = fenix.packages.${system}.combine [
118129
rustToolchain.rustc
119130
rustToolchain.cargo
@@ -128,6 +139,23 @@
128139
cargo = rustTargetToolchain;
129140
rustc = rustTargetToolchain;
130141
};
142+
qemuBin =
143+
if builtins.match "aarch64.*" rustTarget != null then
144+
"qemu-aarch64"
145+
else if builtins.match "armv7.*" rustTarget != null then
146+
"qemu-arm"
147+
else
148+
throw "Unsupported Android target: ${rustTarget}";
149+
# NDK clang wrapper triple: armv7 uses "armv7a-linux-androideabi",
150+
# all others match the Rust target triple.
151+
ndkClangTriple =
152+
if builtins.match "armv7.*" rustTarget != null then "armv7a-linux-androideabi" else rustTarget;
153+
ndkLinker = "${androidNdk}/toolchains/llvm/prebuilt/linux-x86_64/bin/${ndkClangTriple}${ANDROID_API_LEVEL}-clang";
154+
cargoTargetPrefix = "CARGO_TARGET_${
155+
builtins.replaceStrings [ "-" ] [ "_" ] (pkgs.lib.toUpper rustTarget)
156+
}";
157+
cargoRunnerEnvVar = "${cargoTargetPrefix}_RUNNER";
158+
cargoLinkerEnvVar = "${cargoTargetPrefix}_LINKER";
131159
in
132160
rustPlatform.buildRustPackage {
133161
pname = "libbitcoinkernel-${rustTarget}";
@@ -141,6 +169,9 @@
141169
androidPkgs.cmake
142170
androidPkgs.boost.dev
143171
androidSdk
172+
]
173+
++ pkgs.lib.optionals canTest [
174+
pkgs.qemu
144175
];
145176

146177
ANDROID_HOME = "${androidSdk}/libexec/android-sdk";
@@ -150,17 +181,24 @@
150181
# cargoBuildHook hardcodes the host --target at
151182
# derivation time, so we bypass it for cross builds.
152183
dontCargoBuild = true;
153-
doCheck = false;
184+
doCheck = canTest;
154185
buildPhase = ''
155-
cargo build -p libbitcoinkernel-sys --target ${rustTarget} --offline --release
156-
'';
186+
cargo build -p libbitcoinkernel-sys --target ${rustTarget} --offline --release
187+
'';
188+
checkPhase = pkgs.lib.optionalString canTest ''
189+
export ${cargoLinkerEnvVar}=${ndkLinker}
190+
export ${cargoRunnerEnvVar}=${pkgs.qemu}/bin/${qemuBin}
191+
export QEMU_LD_PREFIX=${androidNdk}/toolchains/llvm/prebuilt/linux-x86_64/sysroot
192+
export RUSTFLAGS="-C target-feature=+crt-static"
193+
cargo test --target ${rustTarget} --offline --release --verbose
194+
'';
157195
installPhase = ''
158-
mkdir -p $out/lib $out/include
159-
find target/${rustTarget}/release -path "*/out/install/lib/*.a" \
160-
-exec cp {} $out/lib/ \;
161-
find target/${rustTarget}/release -path "*/out/install/include/*" \
162-
-exec cp {} $out/include/ \;
163-
'';
196+
mkdir -p $out/lib $out/include
197+
find target/${rustTarget}/release -path "*/out/install/lib/*.a" \
198+
-exec cp {} $out/lib/ \;
199+
find target/${rustTarget}/release -path "*/out/install/include/*" \
200+
-exec cp {} $out/include/ \;
201+
'';
164202
};
165203
in
166204
{

0 commit comments

Comments
 (0)