Skip to content

Commit 9890486

Browse files
authored
feat(core): add mobile_entry_point macro (#4983)
1 parent 16360ae commit 9890486

File tree

11 files changed

+126
-29
lines changed

11 files changed

+126
-29
lines changed

.changes/build-android-env-vars.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri-build": patch
3+
---
4+
5+
Set environment variables used by `tauri::mobile_entry_point`.

.changes/mobile-entry-point-macro.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri-macros": minor
3+
---
4+
5+
Added the `mobile_entry_point` macro.

.changes/tauri-mobile-entry-point.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri": minor
3+
---
4+
5+
Export types required by the `mobile_entry_point` macro.

core/tauri-build/src/lib.rs

+16
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,22 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
219219
}
220220
let config: Config = serde_json::from_value(config)?;
221221

222+
let s = config.tauri.bundle.identifier.split('.');
223+
let last = s.clone().count() - 1;
224+
let mut app_name = String::new();
225+
let mut domain = String::new();
226+
for (i, w) in s.enumerate() {
227+
if i == last {
228+
app_name.push_str(w);
229+
} else {
230+
domain.push_str(w);
231+
domain.push('_');
232+
}
233+
}
234+
domain.pop();
235+
println!("cargo:rustc-env=TAURI_ANDROID_DOMAIN={}", domain);
236+
println!("cargo:rustc-env=TAURI_ANDROID_APP_NAME={}", app_name);
237+
222238
cfg_alias("dev", !has_feature("custom-protocol"));
223239

224240
let mut manifest = Manifest::from_path("Cargo.toml")?;

core/tauri-macros/src/lib.rs

+6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use syn::{parse_macro_input, DeriveInput, ItemFn};
88

99
mod command;
1010
mod command_module;
11+
mod mobile;
1112
mod runtime;
1213

1314
#[macro_use]
@@ -24,6 +25,11 @@ pub fn command(attributes: TokenStream, item: TokenStream) -> TokenStream {
2425
command::wrapper(attributes, item)
2526
}
2627

28+
#[proc_macro_attribute]
29+
pub fn mobile_entry_point(attributes: TokenStream, item: TokenStream) -> TokenStream {
30+
mobile::entry_point(attributes, item)
31+
}
32+
2733
/// Accepts a list of commands functions. Creates a handler that allows commands to be called from JS with invoke().
2834
///
2935
/// # Examples

core/tauri-macros/src/mobile.rs

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
use proc_macro::TokenStream;
2+
use proc_macro2::TokenStream as TokenStream2;
3+
use quote::{format_ident, quote};
4+
use std::env::var;
5+
use syn::{parse_macro_input, spanned::Spanned, ItemFn};
6+
7+
fn get_env_var(name: &str, error: &mut Option<TokenStream2>, function: &ItemFn) -> TokenStream2 {
8+
match var(name) {
9+
Ok(value) => {
10+
let ident = format_ident!("{}", value);
11+
quote!(#ident)
12+
}
13+
Err(_) => {
14+
error.replace(
15+
syn::Error::new(
16+
function.span(),
17+
format!(
18+
"`{}` env var not set, do you have a build script with tauri-build?",
19+
name,
20+
),
21+
)
22+
.into_compile_error(),
23+
);
24+
quote!()
25+
}
26+
}
27+
}
28+
29+
pub fn entry_point(_attributes: TokenStream, item: TokenStream) -> TokenStream {
30+
let function = parse_macro_input!(item as ItemFn);
31+
let function_name = function.sig.ident.clone();
32+
33+
let mut error = None;
34+
let domain = get_env_var("TAURI_ANDROID_DOMAIN", &mut error, &function);
35+
let app_name = get_env_var("TAURI_ANDROID_APP_NAME", &mut error, &function);
36+
37+
if let Some(e) = error {
38+
quote!(#e).into()
39+
} else {
40+
quote!(
41+
fn stop_unwind<F: FnOnce() -> T, T>(f: F) -> T {
42+
match std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)) {
43+
Ok(t) => t,
44+
Err(err) => {
45+
eprintln!("attempt to unwind out of `rust` with err: {:?}", err);
46+
std::process::abort()
47+
}
48+
}
49+
}
50+
51+
#function
52+
53+
fn _start_app() {
54+
#[cfg(target_os = "android")]
55+
{
56+
use ::tauri::paste;
57+
::tauri::wry_android_binding!(#domain, #app_name, _start_app, ::tauri::wry);
58+
}
59+
stop_unwind(#function_name);
60+
}
61+
62+
#[cfg(not(target_os = "android"))]
63+
#[no_mangle]
64+
#[inline(never)]
65+
pub extern "C" fn start_app() {
66+
_start_app()
67+
}
68+
)
69+
.into()
70+
}
71+
}

core/tauri/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ objc = "0.2"
111111
webview2-com = "0.16.0"
112112
win7-notifications = { version = "0.3.0", optional = true }
113113

114+
[target.'cfg(target_os = "android")'.dependencies]
115+
paste = "1.0"
116+
114117
[target."cfg(windows)".dependencies.windows]
115118
version = "0.37.0"
116119
features = [ "Win32_Foundation" ]

core/tauri/src/lib.rs

+13
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ pub use error::Error;
158158
#[cfg(shell_scope)]
159159
#[doc(hidden)]
160160
pub use regex;
161+
#[cfg(mobile)]
162+
pub use tauri_macros::mobile_entry_point;
161163
pub use tauri_macros::{command, generate_handler};
162164

163165
pub mod api;
@@ -188,6 +190,17 @@ pub use tauri_utils as utils;
188190
#[cfg_attr(doc_cfg, doc(cfg(feature = "wry")))]
189191
pub type Wry = tauri_runtime_wry::Wry<EventLoopMessage>;
190192

193+
#[cfg(all(feature = "wry", target_os = "android"))]
194+
#[cfg_attr(doc_cfg, doc(cfg(all(feature = "wry", target_os = "android"))))]
195+
pub use tauri_runtime_wry::wry::android_binding as wry_android_binding;
196+
197+
#[cfg(all(feature = "wry", target_os = "android"))]
198+
#[doc(hidden)]
199+
pub use paste;
200+
#[cfg(all(feature = "wry", target_os = "android"))]
201+
#[doc(hidden)]
202+
pub use tauri_runtime_wry::wry;
203+
191204
/// `Result<T, ::tauri::Error>`
192205
pub type Result<T> = std::result::Result<T, Error>;
193206

examples/api/src-tauri/Cargo.lock

+1-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/api/src-tauri/Cargo.toml

-2
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,9 @@ window-shadows= "0.2"
4141

4242
[target.'cfg(any(target_os = "android", target_os = "ios"))'.dependencies]
4343
log = "0.4"
44-
tauri-runtime-wry = { path = "../../../core/tauri-runtime-wry/" }
4544

4645
[target.'cfg(target_os = "android")'.dependencies]
4746
android_logger = "0.9.0"
48-
paste = "1.0"
4947

5048
[target.'cfg(target_os = "ios")'.dependencies]
5149
env_logger = "0.9.0"

examples/api/src-tauri/src/mobile.rs

+1-25
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
#[cfg(target_os = "android")]
2-
use tauri_runtime_wry::wry::android_binding;
3-
41
#[cfg(target_os = "android")]
52
fn init_logging(app_name: &str) {
63
android_logger::init_once(
@@ -15,28 +12,7 @@ fn init_logging(_app_name: &str) {
1512
env_logger::init();
1613
}
1714

18-
fn stop_unwind<F: FnOnce() -> T, T>(f: F) -> T {
19-
match std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)) {
20-
Ok(t) => t,
21-
Err(err) => {
22-
eprintln!("attempt to unwind out of `rust` with err: {:?}", err);
23-
std::process::abort()
24-
}
25-
}
26-
}
27-
28-
fn _start_app() {
29-
stop_unwind(main);
30-
}
31-
32-
#[no_mangle]
33-
#[inline(never)]
34-
pub extern "C" fn start_app() {
35-
#[cfg(target_os = "android")]
36-
android_binding!(com_tauri, api, _start_app, tauri_runtime_wry::wry);
37-
_start_app()
38-
}
39-
15+
#[tauri::mobile_entry_point]
4016
fn main() {
4117
super::AppBuilder::new()
4218
.setup(|app| {

0 commit comments

Comments
 (0)