Răsfoiți Sursa

feat(core): add `mobile_entry_point` macro (#4983)

Lucas Fernandes Nogueira 3 ani în urmă
părinte
comite
9890486321

+ 5 - 0
.changes/build-android-env-vars.md

@@ -0,0 +1,5 @@
+---
+"tauri-build": patch
+---
+
+Set environment variables used by `tauri::mobile_entry_point`.

+ 5 - 0
.changes/mobile-entry-point-macro.md

@@ -0,0 +1,5 @@
+---
+"tauri-macros": minor
+---
+
+Added the `mobile_entry_point` macro.

+ 5 - 0
.changes/tauri-mobile-entry-point.md

@@ -0,0 +1,5 @@
+---
+"tauri": minor
+---
+
+Export types required by the `mobile_entry_point` macro.

+ 16 - 0
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")?;

+ 6 - 0
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

+ 71 - 0
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<TokenStream2>, 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<F: FnOnce() -> 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()
+  }
+}

+ 3 - 0
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" ]

+ 13 - 0
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<EventLoopMessage>;
 
+#[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<T, ::tauri::Error>`
 pub type Result<T> = std::result::Result<T, Error>;
 

+ 1 - 2
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",

+ 0 - 2
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"

+ 1 - 25
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<F: FnOnce() -> 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| {