mobile_entry_point/
lib.rs

1#![recursion_limit = "256"]
2
3use quote::quote;
4use syn::parse_macro_input;
5
6#[proc_macro_attribute]
7pub fn mobile_entry_point(
8    _args: proc_macro::TokenStream,
9    input: proc_macro::TokenStream,
10) -> proc_macro::TokenStream {
11    let func = parse_macro_input!(input as syn::ItemFn);
12    let name = &func.sig.ident;
13
14    let expanded = quote! {
15        fn stop_unwind<F: FnOnce() -> T, T>(f: F) -> T {
16            match std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)) {
17                Ok(t) => t,
18                Err(err) => {
19                    eprintln!("attempt to unwind out of `rust` with err: {:?}", err);
20                    std::process::abort()
21                }
22            }
23        }
24
25        #[cfg_attr(target_os = "android", ndk_glue::main(
26            backtrace = "on",
27            ndk_glue = "ndk_glue",
28        ))]
29        fn _start_app() {
30            #func
31            stop_unwind(|| #name());
32        }
33
34        #[cfg(not(target_os = "android"))]
35        #[no_mangle]
36        #[inline(never)]
37        pub extern "C" fn start_app() {
38            _start_app()
39        }
40    };
41    //panic!("{}", expanded.to_string());
42    expanded.into()
43}