From 9890486321c9c79ccfb7c547fafee85b5c3ffa71 Mon Sep 17 00:00:00 2001 From: Lucas Fernandes Nogueira Date: Sun, 21 Aug 2022 10:35:34 -0300 Subject: [PATCH] feat(core): add `mobile_entry_point` macro (#4983) --- .changes/build-android-env-vars.md | 5 ++ .changes/mobile-entry-point-macro.md | 5 ++ .changes/tauri-mobile-entry-point.md | 5 ++ core/tauri-build/src/lib.rs | 16 +++++++ core/tauri-macros/src/lib.rs | 6 +++ core/tauri-macros/src/mobile.rs | 71 ++++++++++++++++++++++++++++ core/tauri/Cargo.toml | 3 ++ core/tauri/src/lib.rs | 13 +++++ examples/api/src-tauri/Cargo.lock | 3 +- examples/api/src-tauri/Cargo.toml | 2 - examples/api/src-tauri/src/mobile.rs | 26 +--------- 11 files changed, 126 insertions(+), 29 deletions(-) create mode 100644 .changes/build-android-env-vars.md create mode 100644 .changes/mobile-entry-point-macro.md create mode 100644 .changes/tauri-mobile-entry-point.md create mode 100644 core/tauri-macros/src/mobile.rs diff --git a/.changes/build-android-env-vars.md b/.changes/build-android-env-vars.md new file mode 100644 index 000000000..7091ba159 --- /dev/null +++ b/.changes/build-android-env-vars.md @@ -0,0 +1,5 @@ +--- +"tauri-build": patch +--- + +Set environment variables used by `tauri::mobile_entry_point`. diff --git a/.changes/mobile-entry-point-macro.md b/.changes/mobile-entry-point-macro.md new file mode 100644 index 000000000..8b39085e8 --- /dev/null +++ b/.changes/mobile-entry-point-macro.md @@ -0,0 +1,5 @@ +--- +"tauri-macros": minor +--- + +Added the `mobile_entry_point` macro. diff --git a/.changes/tauri-mobile-entry-point.md b/.changes/tauri-mobile-entry-point.md new file mode 100644 index 000000000..6e57b9767 --- /dev/null +++ b/.changes/tauri-mobile-entry-point.md @@ -0,0 +1,5 @@ +--- +"tauri": minor +--- + +Export types required by the `mobile_entry_point` macro. diff --git a/core/tauri-build/src/lib.rs b/core/tauri-build/src/lib.rs index 5ddbb3730..98ad640ae 100644 --- a/core/tauri-build/src/lib.rs +++ b/core/tauri-build/src/lib.rs @@ -219,6 +219,22 @@ pub fn try_build(attributes: Attributes) -> Result<()> { } let config: Config = serde_json::from_value(config)?; + let s = config.tauri.bundle.identifier.split('.'); + let last = s.clone().count() - 1; + let mut app_name = String::new(); + let mut domain = String::new(); + for (i, w) in s.enumerate() { + if i == last { + app_name.push_str(w); + } else { + domain.push_str(w); + domain.push('_'); + } + } + domain.pop(); + println!("cargo:rustc-env=TAURI_ANDROID_DOMAIN={}", domain); + println!("cargo:rustc-env=TAURI_ANDROID_APP_NAME={}", app_name); + cfg_alias("dev", !has_feature("custom-protocol")); let mut manifest = Manifest::from_path("Cargo.toml")?; diff --git a/core/tauri-macros/src/lib.rs b/core/tauri-macros/src/lib.rs index 3af378078..77300d45d 100644 --- a/core/tauri-macros/src/lib.rs +++ b/core/tauri-macros/src/lib.rs @@ -8,6 +8,7 @@ use syn::{parse_macro_input, DeriveInput, ItemFn}; mod command; mod command_module; +mod mobile; mod runtime; #[macro_use] @@ -24,6 +25,11 @@ pub fn command(attributes: TokenStream, item: TokenStream) -> TokenStream { command::wrapper(attributes, item) } +#[proc_macro_attribute] +pub fn mobile_entry_point(attributes: TokenStream, item: TokenStream) -> TokenStream { + mobile::entry_point(attributes, item) +} + /// Accepts a list of commands functions. Creates a handler that allows commands to be called from JS with invoke(). /// /// # Examples diff --git a/core/tauri-macros/src/mobile.rs b/core/tauri-macros/src/mobile.rs new file mode 100644 index 000000000..e98b647de --- /dev/null +++ b/core/tauri-macros/src/mobile.rs @@ -0,0 +1,71 @@ +use proc_macro::TokenStream; +use proc_macro2::TokenStream as TokenStream2; +use quote::{format_ident, quote}; +use std::env::var; +use syn::{parse_macro_input, spanned::Spanned, ItemFn}; + +fn get_env_var(name: &str, error: &mut Option, function: &ItemFn) -> TokenStream2 { + match var(name) { + Ok(value) => { + let ident = format_ident!("{}", value); + quote!(#ident) + } + Err(_) => { + error.replace( + syn::Error::new( + function.span(), + format!( + "`{}` env var not set, do you have a build script with tauri-build?", + name, + ), + ) + .into_compile_error(), + ); + quote!() + } + } +} + +pub fn entry_point(_attributes: TokenStream, item: TokenStream) -> TokenStream { + let function = parse_macro_input!(item as ItemFn); + let function_name = function.sig.ident.clone(); + + let mut error = None; + let domain = get_env_var("TAURI_ANDROID_DOMAIN", &mut error, &function); + let app_name = get_env_var("TAURI_ANDROID_APP_NAME", &mut error, &function); + + if let Some(e) = error { + quote!(#e).into() + } else { + quote!( + fn stop_unwind T, T>(f: F) -> T { + match std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)) { + Ok(t) => t, + Err(err) => { + eprintln!("attempt to unwind out of `rust` with err: {:?}", err); + std::process::abort() + } + } + } + + #function + + fn _start_app() { + #[cfg(target_os = "android")] + { + use ::tauri::paste; + ::tauri::wry_android_binding!(#domain, #app_name, _start_app, ::tauri::wry); + } + stop_unwind(#function_name); + } + + #[cfg(not(target_os = "android"))] + #[no_mangle] + #[inline(never)] + pub extern "C" fn start_app() { + _start_app() + } + ) + .into() + } +} diff --git a/core/tauri/Cargo.toml b/core/tauri/Cargo.toml index 879245f65..459b64c9c 100644 --- a/core/tauri/Cargo.toml +++ b/core/tauri/Cargo.toml @@ -111,6 +111,9 @@ objc = "0.2" webview2-com = "0.16.0" win7-notifications = { version = "0.3.0", optional = true } +[target.'cfg(target_os = "android")'.dependencies] +paste = "1.0" + [target."cfg(windows)".dependencies.windows] version = "0.37.0" features = [ "Win32_Foundation" ] diff --git a/core/tauri/src/lib.rs b/core/tauri/src/lib.rs index 332df1662..42a321a12 100644 --- a/core/tauri/src/lib.rs +++ b/core/tauri/src/lib.rs @@ -158,6 +158,8 @@ pub use error::Error; #[cfg(shell_scope)] #[doc(hidden)] pub use regex; +#[cfg(mobile)] +pub use tauri_macros::mobile_entry_point; pub use tauri_macros::{command, generate_handler}; pub mod api; @@ -188,6 +190,17 @@ pub use tauri_utils as utils; #[cfg_attr(doc_cfg, doc(cfg(feature = "wry")))] pub type Wry = tauri_runtime_wry::Wry; +#[cfg(all(feature = "wry", target_os = "android"))] +#[cfg_attr(doc_cfg, doc(cfg(all(feature = "wry", target_os = "android"))))] +pub use tauri_runtime_wry::wry::android_binding as wry_android_binding; + +#[cfg(all(feature = "wry", target_os = "android"))] +#[doc(hidden)] +pub use paste; +#[cfg(all(feature = "wry", target_os = "android"))] +#[doc(hidden)] +pub use tauri_runtime_wry::wry; + /// `Result` pub type Result = std::result::Result; diff --git a/examples/api/src-tauri/Cargo.lock b/examples/api/src-tauri/Cargo.lock index e868532a7..73bd19c32 100644 --- a/examples/api/src-tauri/Cargo.lock +++ b/examples/api/src-tauri/Cargo.lock @@ -113,12 +113,10 @@ dependencies = [ "android_logger", "env_logger 0.9.0", "log", - "paste", "serde", "serde_json", "tauri", "tauri-build", - "tauri-runtime-wry", "tiny_http", "window-shadows", "window-vibrancy", @@ -3196,6 +3194,7 @@ dependencies = [ "open", "os_info", "os_pipe", + "paste", "percent-encoding", "png 0.17.5", "rand 0.8.5", diff --git a/examples/api/src-tauri/Cargo.toml b/examples/api/src-tauri/Cargo.toml index cbcd8c1aa..92d75446c 100644 --- a/examples/api/src-tauri/Cargo.toml +++ b/examples/api/src-tauri/Cargo.toml @@ -41,11 +41,9 @@ window-shadows= "0.2" [target.'cfg(any(target_os = "android", target_os = "ios"))'.dependencies] log = "0.4" -tauri-runtime-wry = { path = "../../../core/tauri-runtime-wry/" } [target.'cfg(target_os = "android")'.dependencies] android_logger = "0.9.0" -paste = "1.0" [target.'cfg(target_os = "ios")'.dependencies] env_logger = "0.9.0" diff --git a/examples/api/src-tauri/src/mobile.rs b/examples/api/src-tauri/src/mobile.rs index 8d47ad0ed..958fadd2d 100644 --- a/examples/api/src-tauri/src/mobile.rs +++ b/examples/api/src-tauri/src/mobile.rs @@ -1,6 +1,3 @@ -#[cfg(target_os = "android")] -use tauri_runtime_wry::wry::android_binding; - #[cfg(target_os = "android")] fn init_logging(app_name: &str) { android_logger::init_once( @@ -15,28 +12,7 @@ fn init_logging(_app_name: &str) { env_logger::init(); } -fn stop_unwind T, T>(f: F) -> T { - match std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)) { - Ok(t) => t, - Err(err) => { - eprintln!("attempt to unwind out of `rust` with err: {:?}", err); - std::process::abort() - } - } -} - -fn _start_app() { - stop_unwind(main); -} - -#[no_mangle] -#[inline(never)] -pub extern "C" fn start_app() { - #[cfg(target_os = "android")] - android_binding!(com_tauri, api, _start_app, tauri_runtime_wry::wry); - _start_app() -} - +#[tauri::mobile_entry_point] fn main() { super::AppBuilder::new() .setup(|app| {