Migrate to Rust 1.75.0 and NDK 26.1.10909125

Closes Electric-Coin-Company/zcash-android-wallet-sdk#317.
This commit is contained in:
Jack Grigg 2024-01-11 00:17:14 +00:00 committed by str4d
parent f6eb37731f
commit 1bf2f84837
4 changed files with 107 additions and 6 deletions

View File

@ -18,7 +18,7 @@ runs:
ANDROID_ROOT=/usr/local/lib/android
ANDROID_SDK_ROOT=${ANDROID_ROOT}/sdk
SDKMANAGER=${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager
echo "y" | $SDKMANAGER "ndk;22.1.7171670"
echo "y" | $SDKMANAGER "ndk;26.1.10909125"
- name: Setup Rust
shell: bash
run: |

101
backend-lib/build.rs Normal file
View File

@ -0,0 +1,101 @@
use std::env;
use std::ffi::OsStr;
use std::path::PathBuf;
use std::process::Command;
/// The Clang version that the NDK version pinned in `gradle.properties` should be using.
const ANDROID_NDK_CLANG_VERSION: &str = "17";
fn main() {
setup_x86_64_android_workaround();
}
/// Adds a temporary workaround for [an issue] with the Rust compiler and Android when
/// compiling for x86_64 devices.
///
/// The Android NDK used to include `libgcc` for unwind support (which is required by Rust
/// among others). From NDK r23, `libgcc` is removed, replaced by LLVM's `libunwind`.
/// However, `libgcc` was ambiently providing other compiler builtins, one of which we
/// require: `__extenddftf2` for software floating-point emulation. This is used by SQLite
/// (via the `rusqlite` crate), which defines a `LONGDOUBLE_TYPE` type as `long double`.
///
/// Rust uses a `compiler-builtins` crate that does not provide `__extenddftf2` because
/// [it involves floating-point types that are not supported by Rust][unsupported]. For
/// some reason, they _do_ export this symbol for `aarch64-linux-android`, but they do not
/// for `x86_64-linux-android`. Thus we run into a problem when trying to compile and run
/// the SDK on an x86_64 emulator.
///
/// The workaround comes from [this Mozilla PR]: we tell Cargo to statically link the
/// builtins from the Clang runtime provided inside the NDK, to provide this symbol.
///
/// [an issue]: https://github.com/rust-lang/rust/issues/109717
/// [this Mozilla PR]:https://github.com/mozilla/application-services/pull/5442
/// [unsupported]: https://github.com/rust-lang/compiler-builtins#unimplemented-functions
fn setup_x86_64_android_workaround() {
let target_os = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS not set");
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH not set");
if target_arch == "x86_64" && target_os == "android" {
let cc = if let Some(cc) = env::var_os("RUST_ANDROID_GRADLE_CC") {
// We are building in the context of the `org.mozilla.rust-android-gradle`
// plugin, which knows where the NDK is and provides the Clang path.
PathBuf::from(cc)
} else {
// We are probably building directly on the CLI. Construct a path to Clang.
let android_ndk_home =
env::var_os("ANDROID_NDK_HOME").expect("ANDROID_NDK_HOME not set");
let build_os = match env::consts::OS {
"linux" => "linux",
"macos" => "darwin",
"windows" => "windows",
_ => panic!(
"Unsupported OS. You must use either Linux, MacOS or Windows to build the crate."
),
};
let mut cc = PathBuf::from(android_ndk_home);
cc.push("toolchains");
cc.push("llvm");
cc.push("prebuilt");
cc.push(format!("{build_os}-x86_64"));
cc.push("bin");
cc.push("clang");
cc.set_extension(env::consts::EXE_EXTENSION);
cc
};
let mut link_path = cc
.ancestors()
.nth(2)
.expect("path format is known")
.join("lib");
link_path.push("clang");
link_path.push(get_clang_version(&cc));
link_path.push("lib");
link_path.push("linux");
if link_path.exists() {
println!("cargo:rustc-link-search={}", link_path.display());
println!("cargo:rustc-link-lib=static=clang_rt.builtins-x86_64-android");
} else {
panic!("Path {} does not exist", link_path.display());
}
}
}
fn get_clang_version(cc: impl AsRef<OsStr>) -> String {
let clang_version_output = Command::new(cc)
.arg("--version")
.output()
.ok()
.and_then(|o| String::from_utf8(o.stdout).ok());
clang_version_output
.as_deref()
.and_then(|s| s.split_once("clang version "))
.and_then(|(_, s)| s.split_once('.'))
.map(|(major_version, _)| major_version)
// If we couldn't run Clang for some reason, default to the Clang version that the
// NDK version pinned in `gradle.properties` should be using.
.unwrap_or(ANDROID_NDK_CLANG_VERSION)
.into()
}

View File

@ -78,10 +78,10 @@ ANDROID_MIN_SDK_VERSION=27
ANDROID_TARGET_SDK_VERSION=33
ANDROID_COMPILE_SDK_VERSION=34
# TODO[#317]: Update NDK to 24.0.7856742
# TODO[#317]: https://github.com/zcash/zcash-android-wallet-sdk/issues/317
# When changing this, be sure to update .github/actions/setup/action.yml
ANDROID_NDK_VERSION=22.1.7171670
# When changing this, be sure to update the following places:
# - .github/actions/setup/action.yml
# - Clang major version in backend-lib/build.rs
ANDROID_NDK_VERSION=26.1.10909125
ANDROID_GRADLE_PLUGIN_VERSION=8.1.1
DETEKT_VERSION=1.23.0

View File

@ -1,5 +1,5 @@
[toolchain]
channel = "1.67.1"
channel = "1.75.0"
targets = [
"armv7-linux-androideabi",
"aarch64-linux-android",