1 extern crate cc;
2
3 use std::env;
4 use std::path::Path;
5
6 // Must be public so the build script of `std` can call it.
main()7 pub fn main() {
8 match env::var("CARGO_CFG_TARGET_OS").unwrap_or_default().as_str() {
9 "android" => build_android(),
10 _ => {}
11 }
12 }
13
14 // Used to detect the value of the `__ANDROID_API__`
15 // builtin #define
16 const MARKER: &str = "BACKTRACE_RS_ANDROID_APIVERSION";
17 const ANDROID_API_C: &str = "
18 BACKTRACE_RS_ANDROID_APIVERSION __ANDROID_API__
19 ";
20
build_android()21 fn build_android() {
22 // Create `android-api.c` on demand.
23 // Required to support calling this from the `std` build script.
24 let out_dir = env::var_os("OUT_DIR").unwrap();
25 let android_api_c = Path::new(&out_dir).join("android-api.c");
26 std::fs::write(&android_api_c, ANDROID_API_C).unwrap();
27
28 let expansion = match cc::Build::new().file(&android_api_c).try_expand() {
29 Ok(result) => result,
30 Err(e) => {
31 eprintln!("warning: android version detection failed while running C compiler: {e}");
32 return;
33 }
34 };
35 let expansion = match std::str::from_utf8(&expansion) {
36 Ok(s) => s,
37 Err(_) => return,
38 };
39 eprintln!("expanded android version detection:\n{expansion}");
40 let i = match expansion.find(MARKER) {
41 Some(i) => i,
42 None => return,
43 };
44 let version = match expansion[i + MARKER.len() + 1..].split_whitespace().next() {
45 Some(s) => s,
46 None => return,
47 };
48 let version = match version.parse::<u32>() {
49 Ok(n) => n,
50 Err(_) => return,
51 };
52 if version >= 21 {
53 println!("cargo:rustc-cfg=feature=\"dl_iterate_phdr\"");
54 }
55 }
56