refactor: autodetect macro variant
Export all main macro per target architecture from embassy-macros, and select the appropriate macro in embassy-executor.
This commit is contained in:
		@@ -29,9 +29,8 @@ flavors = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[features]
 | 
					[features]
 | 
				
			||||||
default = []
 | 
					default = []
 | 
				
			||||||
std = ["embassy-macros/std", "critical-section/std"]
 | 
					std = ["critical-section/std"]
 | 
				
			||||||
wasm = ["dep:wasm-bindgen", "dep:js-sys", "embassy-macros/wasm"]
 | 
					wasm = ["dep:wasm-bindgen", "dep:js-sys"]
 | 
				
			||||||
riscv = ["embassy-macros/riscv"]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Enable nightly-only features
 | 
					# Enable nightly-only features
 | 
				
			||||||
nightly = []
 | 
					nightly = []
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,18 +8,22 @@
 | 
				
			|||||||
pub(crate) mod fmt;
 | 
					pub(crate) mod fmt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(feature = "nightly")]
 | 
					#[cfg(feature = "nightly")]
 | 
				
			||||||
pub use embassy_macros::{main, task};
 | 
					pub use embassy_macros::task;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cfg_if::cfg_if! {
 | 
					cfg_if::cfg_if! {
 | 
				
			||||||
    if #[cfg(cortex_m)] {
 | 
					    if #[cfg(cortex_m)] {
 | 
				
			||||||
        #[path="arch/cortex_m.rs"]
 | 
					        #[path="arch/cortex_m.rs"]
 | 
				
			||||||
        mod arch;
 | 
					        mod arch;
 | 
				
			||||||
        pub use arch::*;
 | 
					        pub use arch::*;
 | 
				
			||||||
 | 
					        #[cfg(feature = "nightly")]
 | 
				
			||||||
 | 
					        pub use embassy_macros::main_cortex_m as main;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if #[cfg(target_arch="riscv32")] {
 | 
					    else if #[cfg(target_arch="riscv32")] {
 | 
				
			||||||
        #[path="arch/riscv32.rs"]
 | 
					        #[path="arch/riscv32.rs"]
 | 
				
			||||||
        mod arch;
 | 
					        mod arch;
 | 
				
			||||||
        pub use arch::*;
 | 
					        pub use arch::*;
 | 
				
			||||||
 | 
					        #[cfg(feature = "nightly")]
 | 
				
			||||||
 | 
					        pub use embassy_macros::main_riscv as main;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if #[cfg(all(target_arch="xtensa", feature = "nightly"))] {
 | 
					    else if #[cfg(all(target_arch="xtensa", feature = "nightly"))] {
 | 
				
			||||||
        #[path="arch/xtensa.rs"]
 | 
					        #[path="arch/xtensa.rs"]
 | 
				
			||||||
@@ -30,11 +34,15 @@ cfg_if::cfg_if! {
 | 
				
			|||||||
        #[path="arch/wasm.rs"]
 | 
					        #[path="arch/wasm.rs"]
 | 
				
			||||||
        mod arch;
 | 
					        mod arch;
 | 
				
			||||||
        pub use arch::*;
 | 
					        pub use arch::*;
 | 
				
			||||||
 | 
					        #[cfg(feature = "nightly")]
 | 
				
			||||||
 | 
					        pub use embassy_macros::main_wasm as main;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if #[cfg(feature="std")] {
 | 
					    else if #[cfg(feature="std")] {
 | 
				
			||||||
        #[path="arch/std.rs"]
 | 
					        #[path="arch/std.rs"]
 | 
				
			||||||
        mod arch;
 | 
					        mod arch;
 | 
				
			||||||
        pub use arch::*;
 | 
					        pub use arch::*;
 | 
				
			||||||
 | 
					        #[cfg(feature = "nightly")]
 | 
				
			||||||
 | 
					        pub use embassy_macros::main_std as main;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,9 +21,5 @@ proc-macro2 = "1.0.29"
 | 
				
			|||||||
proc-macro = true
 | 
					proc-macro = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[features]
 | 
					[features]
 | 
				
			||||||
std = []
 | 
					 | 
				
			||||||
wasm = []
 | 
					 | 
				
			||||||
riscv = []
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Enabling this cause interrupt::take! to require embassy-executor
 | 
					# Enabling this cause interrupt::take! to require embassy-executor
 | 
				
			||||||
rtos-trace-interrupt = []
 | 
					rtos-trace-interrupt = []
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -45,7 +45,7 @@ pub fn task(args: TokenStream, item: TokenStream) -> TokenStream {
 | 
				
			|||||||
    task::run(args, f).unwrap_or_else(|x| x).into()
 | 
					    task::run(args, f).unwrap_or_else(|x| x).into()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Creates a new `executor` instance and declares an application entry point spawning the corresponding function body as an async task.
 | 
					/// Creates a new `executor` instance and declares an application entry point for Cortex-M spawning the corresponding function body as an async task.
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// The following restrictions apply:
 | 
					/// The following restrictions apply:
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
@@ -64,10 +64,85 @@ pub fn task(args: TokenStream, item: TokenStream) -> TokenStream {
 | 
				
			|||||||
/// }
 | 
					/// }
 | 
				
			||||||
/// ```
 | 
					/// ```
 | 
				
			||||||
#[proc_macro_attribute]
 | 
					#[proc_macro_attribute]
 | 
				
			||||||
pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
 | 
					pub fn main_cortex_m(args: TokenStream, item: TokenStream) -> TokenStream {
 | 
				
			||||||
    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
 | 
					    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
 | 
				
			||||||
    let f = syn::parse_macro_input!(item as syn::ItemFn);
 | 
					    let f = syn::parse_macro_input!(item as syn::ItemFn);
 | 
				
			||||||
    main::run(args, f).unwrap_or_else(|x| x).into()
 | 
					    main::run(args, f, main::cortex_m()).unwrap_or_else(|x| x).into()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Creates a new `executor` instance and declares an application entry point for RISC-V spawning the corresponding function body as an async task.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// The following restrictions apply:
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// * The function must accept exactly 1 parameter, an `embassy_executor::Spawner` handle that it can use to spawn additional tasks.
 | 
				
			||||||
 | 
					/// * The function must be declared `async`.
 | 
				
			||||||
 | 
					/// * The function must not use generics.
 | 
				
			||||||
 | 
					/// * Only a single `main` task may be declared.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// ## Examples
 | 
				
			||||||
 | 
					/// Spawning a task:
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// ``` rust
 | 
				
			||||||
 | 
					/// #[embassy_executor::main]
 | 
				
			||||||
 | 
					/// async fn main(_s: embassy_executor::Spawner) {
 | 
				
			||||||
 | 
					///     // Function body
 | 
				
			||||||
 | 
					/// }
 | 
				
			||||||
 | 
					/// ```
 | 
				
			||||||
 | 
					#[proc_macro_attribute]
 | 
				
			||||||
 | 
					pub fn main_riscv(args: TokenStream, item: TokenStream) -> TokenStream {
 | 
				
			||||||
 | 
					    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
 | 
				
			||||||
 | 
					    let f = syn::parse_macro_input!(item as syn::ItemFn);
 | 
				
			||||||
 | 
					    main::run(args, f, main::riscv()).unwrap_or_else(|x| x).into()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Creates a new `executor` instance and declares an application entry point for STD spawning the corresponding function body as an async task.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// The following restrictions apply:
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// * The function must accept exactly 1 parameter, an `embassy_executor::Spawner` handle that it can use to spawn additional tasks.
 | 
				
			||||||
 | 
					/// * The function must be declared `async`.
 | 
				
			||||||
 | 
					/// * The function must not use generics.
 | 
				
			||||||
 | 
					/// * Only a single `main` task may be declared.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// ## Examples
 | 
				
			||||||
 | 
					/// Spawning a task:
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// ``` rust
 | 
				
			||||||
 | 
					/// #[embassy_executor::main]
 | 
				
			||||||
 | 
					/// async fn main(_s: embassy_executor::Spawner) {
 | 
				
			||||||
 | 
					///     // Function body
 | 
				
			||||||
 | 
					/// }
 | 
				
			||||||
 | 
					/// ```
 | 
				
			||||||
 | 
					#[proc_macro_attribute]
 | 
				
			||||||
 | 
					pub fn main_std(args: TokenStream, item: TokenStream) -> TokenStream {
 | 
				
			||||||
 | 
					    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
 | 
				
			||||||
 | 
					    let f = syn::parse_macro_input!(item as syn::ItemFn);
 | 
				
			||||||
 | 
					    main::run(args, f, main::std()).unwrap_or_else(|x| x).into()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Creates a new `executor` instance and declares an application entry point for WASM spawning the corresponding function body as an async task.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// The following restrictions apply:
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// * The function must accept exactly 1 parameter, an `embassy_executor::Spawner` handle that it can use to spawn additional tasks.
 | 
				
			||||||
 | 
					/// * The function must be declared `async`.
 | 
				
			||||||
 | 
					/// * The function must not use generics.
 | 
				
			||||||
 | 
					/// * Only a single `main` task may be declared.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// ## Examples
 | 
				
			||||||
 | 
					/// Spawning a task:
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// ``` rust
 | 
				
			||||||
 | 
					/// #[embassy_executor::main]
 | 
				
			||||||
 | 
					/// async fn main(_s: embassy_executor::Spawner) {
 | 
				
			||||||
 | 
					///     // Function body
 | 
				
			||||||
 | 
					/// }
 | 
				
			||||||
 | 
					/// ```
 | 
				
			||||||
 | 
					#[proc_macro_attribute]
 | 
				
			||||||
 | 
					pub fn main_wasm(args: TokenStream, item: TokenStream) -> TokenStream {
 | 
				
			||||||
 | 
					    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
 | 
				
			||||||
 | 
					    let f = syn::parse_macro_input!(item as syn::ItemFn);
 | 
				
			||||||
 | 
					    main::run(args, f, main::wasm()).unwrap_or_else(|x| x).into()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[proc_macro_attribute]
 | 
					#[proc_macro_attribute]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,62 @@ use crate::util::ctxt::Ctxt;
 | 
				
			|||||||
#[derive(Debug, FromMeta)]
 | 
					#[derive(Debug, FromMeta)]
 | 
				
			||||||
struct Args {}
 | 
					struct Args {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn run(args: syn::AttributeArgs, f: syn::ItemFn) -> Result<TokenStream, TokenStream> {
 | 
					pub fn riscv() -> TokenStream {
 | 
				
			||||||
 | 
					    quote! {
 | 
				
			||||||
 | 
					        #[riscv_rt::entry]
 | 
				
			||||||
 | 
					        fn main() -> ! {
 | 
				
			||||||
 | 
					            let mut executor = ::embassy_executor::Executor::new();
 | 
				
			||||||
 | 
					            let executor = unsafe { __make_static(&mut executor) };
 | 
				
			||||||
 | 
					            executor.run(|spawner| {
 | 
				
			||||||
 | 
					                spawner.must_spawn(__embassy_main(spawner));
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn cortex_m() -> TokenStream {
 | 
				
			||||||
 | 
					    quote! {
 | 
				
			||||||
 | 
					        #[cortex_m_rt::entry]
 | 
				
			||||||
 | 
					        fn main() -> ! {
 | 
				
			||||||
 | 
					            let mut executor = ::embassy_executor::Executor::new();
 | 
				
			||||||
 | 
					            let executor = unsafe { __make_static(&mut executor) };
 | 
				
			||||||
 | 
					            executor.run(|spawner| {
 | 
				
			||||||
 | 
					                spawner.must_spawn(__embassy_main(spawner));
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn wasm() -> TokenStream {
 | 
				
			||||||
 | 
					    quote! {
 | 
				
			||||||
 | 
					        #[wasm_bindgen::prelude::wasm_bindgen(start)]
 | 
				
			||||||
 | 
					        pub fn main() -> Result<(), wasm_bindgen::JsValue> {
 | 
				
			||||||
 | 
					            static EXECUTOR: ::embassy_executor::_export::StaticCell<::embassy_executor::Executor> = ::embassy_executor::_export::StaticCell::new();
 | 
				
			||||||
 | 
					            let executor = EXECUTOR.init(::embassy_executor::Executor::new());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            executor.start(|spawner| {
 | 
				
			||||||
 | 
					                spawner.spawn(__embassy_main(spawner)).unwrap();
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Ok(())
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn std() -> TokenStream {
 | 
				
			||||||
 | 
					    quote! {
 | 
				
			||||||
 | 
					        fn main() -> ! {
 | 
				
			||||||
 | 
					            let mut executor = ::embassy_executor::Executor::new();
 | 
				
			||||||
 | 
					            let executor = unsafe { __make_static(&mut executor) };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            executor.run(|spawner| {
 | 
				
			||||||
 | 
					                spawner.must_spawn(__embassy_main(spawner));
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn run(args: syn::AttributeArgs, f: syn::ItemFn, main: TokenStream) -> Result<TokenStream, TokenStream> {
 | 
				
			||||||
    #[allow(unused_variables)]
 | 
					    #[allow(unused_variables)]
 | 
				
			||||||
    let args = Args::from_list(&args).map_err(|e| e.write_errors())?;
 | 
					    let args = Args::from_list(&args).map_err(|e| e.write_errors())?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -30,57 +85,6 @@ pub fn run(args: syn::AttributeArgs, f: syn::ItemFn) -> Result<TokenStream, Toke
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    let f_body = f.block;
 | 
					    let f_body = f.block;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[cfg(feature = "wasm")]
 | 
					 | 
				
			||||||
    let main = quote! {
 | 
					 | 
				
			||||||
        #[wasm_bindgen::prelude::wasm_bindgen(start)]
 | 
					 | 
				
			||||||
        pub fn main() -> Result<(), wasm_bindgen::JsValue> {
 | 
					 | 
				
			||||||
            static EXECUTOR: ::embassy_executor::_export::StaticCell<::embassy_executor::Executor> = ::embassy_executor::_export::StaticCell::new();
 | 
					 | 
				
			||||||
            let executor = EXECUTOR.init(::embassy_executor::Executor::new());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            executor.start(|spawner| {
 | 
					 | 
				
			||||||
                spawner.spawn(__embassy_main(spawner)).unwrap();
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            Ok(())
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[cfg(all(feature = "std", not(feature = "wasm"), not(feature = "riscv")))]
 | 
					 | 
				
			||||||
    let main = quote! {
 | 
					 | 
				
			||||||
        fn main() -> ! {
 | 
					 | 
				
			||||||
            let mut executor = ::embassy_executor::Executor::new();
 | 
					 | 
				
			||||||
            let executor = unsafe { __make_static(&mut executor) };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            executor.run(|spawner| {
 | 
					 | 
				
			||||||
                spawner.must_spawn(__embassy_main(spawner));
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[cfg(all(not(feature = "std"), not(feature = "wasm"), not(feature = "riscv")))]
 | 
					 | 
				
			||||||
    let main = quote! {
 | 
					 | 
				
			||||||
        #[cortex_m_rt::entry]
 | 
					 | 
				
			||||||
        fn main() -> ! {
 | 
					 | 
				
			||||||
            let mut executor = ::embassy_executor::Executor::new();
 | 
					 | 
				
			||||||
            let executor = unsafe { __make_static(&mut executor) };
 | 
					 | 
				
			||||||
            executor.run(|spawner| {
 | 
					 | 
				
			||||||
                spawner.must_spawn(__embassy_main(spawner));
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[cfg(all(not(feature = "std"), not(feature = "wasm"), feature = "riscv"))]
 | 
					 | 
				
			||||||
    let main = quote! {
 | 
					 | 
				
			||||||
        #[riscv_rt::entry]
 | 
					 | 
				
			||||||
        fn main() -> ! {
 | 
					 | 
				
			||||||
            let mut executor = ::embassy_executor::Executor::new();
 | 
					 | 
				
			||||||
            let executor = unsafe { __make_static(&mut executor) };
 | 
					 | 
				
			||||||
            executor.run(|spawner| {
 | 
					 | 
				
			||||||
                spawner.must_spawn(__embassy_main(spawner));
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let result = quote! {
 | 
					    let result = quote! {
 | 
				
			||||||
        #[::embassy_executor::task()]
 | 
					        #[::embassy_executor::task()]
 | 
				
			||||||
        async fn __embassy_main(#fargs) {
 | 
					        async fn __embassy_main(#fargs) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user