From c4d4f6e06d159a4f87b53fa09eebf4156e2ccd36 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Tue, 7 Jan 2025 16:24:33 +0100 Subject: [PATCH] android: Set SDK/API level via version-suffxed `--target` triple We haven't set the SDK/API level via the `__ANDROID_API__` define for a very long time and so far got away with it. However, while debugging why `backtrace` (and by extension Rust `std` which reuses that crate) wasn't generating symbolicated stacktraces in `panic_log`, and why `findshlibs` wasn't providing the list of loaded libraries to `sentry`, we found that both rely on expanding the `__ANDROID_API__` define via compiling a small C file via `cc` to make the code conditional on SDK/API >= 21: https://github.com/gimli-rs/findshlibs/pull/65 https://github.com/rust-lang/backtrace-rs/pull/415 (It would have been lovely if these crates emitted a `cargo:warning` when the define wasn't set at all, indicating an "incomplete" cross-compiler setup, and/or looked at the runtime Android API version via something like https://github.com/rust-mobile/ndk/pull/479.) Note that `backtrace 0.3.74` / Rust 1.82 (https://github.com/rust-lang/rust/commit/0763a3a) no longer rely on this because Rust 1.82 bumped the minimum SDK/API level to 21: https://github.com/rust-lang/backtrace-rs/pull/656 We could set this define directly, or rely on `clang` to set it for us by appending the SDK/API level to the target triple, of the form `-linux-android`. The latter is more common. Keep in mind that the `cc` crate adds an unversioned `--target=-linux-android` to the command line arguments as well, but clang seems to deduplicate them (or look at the latter `--target` which contains our version). Note that this effectively reverts https://github.com/rust-mobile/xbuild/pull/127/commits/32efed6 because we must now always pass the SDK level via the triple again, even if the host also happens to be Android with the same architecture. --- xbuild/src/cargo/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xbuild/src/cargo/mod.rs b/xbuild/src/cargo/mod.rs index be2cd71..178c19b 100644 --- a/xbuild/src/cargo/mod.rs +++ b/xbuild/src/cargo/mod.rs @@ -281,11 +281,13 @@ impl CargoBuild { pub fn use_android_ndk(&mut self, path: &Path, target_sdk_version: u32) -> Result<()> { let path = dunce::canonicalize(path)?; let ndk_triple = self.target.ndk_triple(); + let ndk_versioned_triple = format!("{ndk_triple}{target_sdk_version}"); self.cfg_tool(Tool::Cc, "clang"); self.cfg_tool(Tool::Cxx, "clang++"); self.cfg_tool(Tool::Ar, "llvm-ar"); self.cfg_tool(Tool::Linker, "clang"); self.set_sysroot(&path); + self.add_cflag(&format!("--target={ndk_versioned_triple}")); self.add_cxxflag("-stdlib=libc++"); let lib_dir = path.join("usr").join("lib").join(ndk_triple); let sdk_lib_dir = lib_dir.join(target_sdk_version.to_string()); @@ -295,9 +297,7 @@ impl CargoBuild { target_sdk_version ); self.use_ld("lld"); - if let Some(triple) = self.triple { - self.add_link_arg(&format!("--target={}", triple)); - } + self.add_link_arg(&format!("--target={ndk_versioned_triple}")); self.add_link_arg(&format!("-B{}", sdk_lib_dir.display())); self.add_link_arg(&format!("-L{}", sdk_lib_dir.display())); self.add_link_arg(&format!("-L{}", lib_dir.display()));