fix: also link libc++abi for RTTI — resolve missing __class_type_info vtable
- Compile all 62 Oboe source files (was headers-only, missing symbols) - Link libc++_static + libc++abi with NDK sysroot search path - Bump linker target from android21 to android26 (fixes pthread_atfork) - Link liblog + libOpenSLES for Oboe runtime deps Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
[target.aarch64-linux-android]
|
[target.aarch64-linux-android]
|
||||||
linker = "aarch64-linux-android21-clang"
|
linker = "aarch64-linux-android26-clang"
|
||||||
|
|
||||||
[target.armv7-linux-androideabi]
|
[target.armv7-linux-androideabi]
|
||||||
linker = "armv7a-linux-androideabi21-clang"
|
linker = "armv7a-linux-androideabi21-clang"
|
||||||
|
|||||||
@@ -4,21 +4,27 @@ fn main() {
|
|||||||
let target = std::env::var("TARGET").unwrap_or_default();
|
let target = std::env::var("TARGET").unwrap_or_default();
|
||||||
|
|
||||||
if target.contains("android") {
|
if target.contains("android") {
|
||||||
// On Android, try to build with Oboe. If Oboe is not available,
|
|
||||||
// fall back to the stub (audio will need to be provided via JNI).
|
|
||||||
let oboe_dir = fetch_oboe();
|
let oboe_dir = fetch_oboe();
|
||||||
match oboe_dir {
|
match oboe_dir {
|
||||||
Some(oboe_path) => {
|
Some(oboe_path) => {
|
||||||
println!("cargo:warning=Building with Oboe from {:?}", oboe_path);
|
println!("cargo:warning=Building with Oboe from {:?}", oboe_path);
|
||||||
cc::Build::new()
|
|
||||||
|
let mut build = cc::Build::new();
|
||||||
|
build
|
||||||
.cpp(true)
|
.cpp(true)
|
||||||
.std("c++17")
|
.std("c++17")
|
||||||
.cpp_link_stdlib(None)
|
.cpp_link_stdlib(None)
|
||||||
.file("cpp/oboe_bridge.cpp")
|
|
||||||
.include("cpp")
|
.include("cpp")
|
||||||
.include(oboe_path.join("include"))
|
.include(oboe_path.join("include"))
|
||||||
|
.include(oboe_path.join("src"))
|
||||||
.define("WZP_HAS_OBOE", None)
|
.define("WZP_HAS_OBOE", None)
|
||||||
.compile("oboe_bridge");
|
.file("cpp/oboe_bridge.cpp");
|
||||||
|
|
||||||
|
// Compile all Oboe source files
|
||||||
|
let src_dir = oboe_path.join("src");
|
||||||
|
add_cpp_files_recursive(&mut build, &src_dir);
|
||||||
|
|
||||||
|
build.compile("oboe_bridge");
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
println!("cargo:warning=Oboe not found, building with stub");
|
println!("cargo:warning=Oboe not found, building with stub");
|
||||||
@@ -36,8 +42,6 @@ fn main() {
|
|||||||
// libc++_static.a — STL (containers, strings, algorithms)
|
// libc++_static.a — STL (containers, strings, algorithms)
|
||||||
// libc++abi.a — ABI (RTTI, exceptions, typeinfo vtables)
|
// libc++abi.a — ABI (RTTI, exceptions, typeinfo vtables)
|
||||||
// Both are required; cc crate's cpp_link_stdlib only handles the first.
|
// Both are required; cc crate's cpp_link_stdlib only handles the first.
|
||||||
//
|
|
||||||
// We also need to tell the linker where to find them in the NDK sysroot.
|
|
||||||
if let Ok(ndk) = std::env::var("ANDROID_NDK_HOME") {
|
if let Ok(ndk) = std::env::var("ANDROID_NDK_HOME") {
|
||||||
let arch = if target.contains("aarch64") {
|
let arch = if target.contains("aarch64") {
|
||||||
"aarch64-linux-android"
|
"aarch64-linux-android"
|
||||||
@@ -53,6 +57,10 @@ fn main() {
|
|||||||
}
|
}
|
||||||
println!("cargo:rustc-link-lib=static=c++_static");
|
println!("cargo:rustc-link-lib=static=c++_static");
|
||||||
println!("cargo:rustc-link-lib=static=c++abi");
|
println!("cargo:rustc-link-lib=static=c++abi");
|
||||||
|
|
||||||
|
// Oboe needs liblog and libOpenSLES from Android
|
||||||
|
println!("cargo:rustc-link-lib=log");
|
||||||
|
println!("cargo:rustc-link-lib=OpenSLES");
|
||||||
} else {
|
} else {
|
||||||
// Non-Android: always use stub
|
// Non-Android: always use stub
|
||||||
cc::Build::new()
|
cc::Build::new()
|
||||||
@@ -64,18 +72,31 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Recursively add all .cpp files from a directory to a cc::Build.
|
||||||
|
fn add_cpp_files_recursive(build: &mut cc::Build, dir: &std::path::Path) {
|
||||||
|
if !dir.is_dir() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for entry in std::fs::read_dir(dir).unwrap() {
|
||||||
|
let entry = entry.unwrap();
|
||||||
|
let path = entry.path();
|
||||||
|
if path.is_dir() {
|
||||||
|
add_cpp_files_recursive(build, &path);
|
||||||
|
} else if path.extension().map_or(false, |e| e == "cpp") {
|
||||||
|
build.file(&path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Try to find or fetch Oboe headers.
|
/// Try to find or fetch Oboe headers.
|
||||||
/// Returns the path to the Oboe source root (containing include/ directory).
|
|
||||||
fn fetch_oboe() -> Option<PathBuf> {
|
fn fetch_oboe() -> Option<PathBuf> {
|
||||||
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
|
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
|
||||||
let oboe_dir = out_dir.join("oboe");
|
let oboe_dir = out_dir.join("oboe");
|
||||||
|
|
||||||
// Check if already fetched
|
|
||||||
if oboe_dir.join("include").join("oboe").join("Oboe.h").exists() {
|
if oboe_dir.join("include").join("oboe").join("Oboe.h").exists() {
|
||||||
return Some(oboe_dir);
|
return Some(oboe_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to clone Oboe from GitHub
|
|
||||||
let status = std::process::Command::new("git")
|
let status = std::process::Command::new("git")
|
||||||
.args([
|
.args([
|
||||||
"clone",
|
"clone",
|
||||||
|
|||||||
BIN
wzp-release.apk
BIN
wzp-release.apk
Binary file not shown.
Reference in New Issue
Block a user