macro: add 'boot' attribute to packages

This is supposed to be a function executed after the 'boot' method has
finished registering the XS callbacks.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2023-07-25 13:40:34 +02:00
parent 63fcccaa50
commit 1017735ad0
2 changed files with 12 additions and 0 deletions

View File

@ -8,6 +8,7 @@ pub struct ModuleAttrs {
pub file_name: Option<String>, pub file_name: Option<String>,
pub lib_name: Option<String>, pub lib_name: Option<String>,
pub write: Option<bool>, pub write: Option<bool>,
pub boot: Option<Ident>,
} }
fn is_ident_check_dup<T>(path: &syn::Path, var: &Option<T>, what: &'static str) -> bool { fn is_ident_check_dup<T>(path: &syn::Path, var: &Option<T>, what: &'static str) -> bool {
@ -29,6 +30,7 @@ impl TryFrom<AttributeArgs> for ModuleAttrs {
let mut file_name = None; let mut file_name = None;
let mut lib_name = None; let mut lib_name = None;
let mut write = None; let mut write = None;
let mut boot = None;
for arg in args { for arg in args {
match arg { match arg {
@ -43,6 +45,8 @@ impl TryFrom<AttributeArgs> for ModuleAttrs {
file_name = Some(expand_env_vars(&litstr)?); file_name = Some(expand_env_vars(&litstr)?);
} else if is_ident_check_dup(&path, &lib_name, "lib") { } else if is_ident_check_dup(&path, &lib_name, "lib") {
lib_name = Some(expand_env_vars(&litstr)?); lib_name = Some(expand_env_vars(&litstr)?);
} else if is_ident_check_dup(&path, &boot, "boot") {
boot = Some(litstr.parse::<Ident>()?);
} else { } else {
error!(path => "unknown argument"); error!(path => "unknown argument");
} }
@ -70,6 +74,7 @@ impl TryFrom<AttributeArgs> for ModuleAttrs {
file_name, file_name,
lib_name, lib_name,
write, write,
boot,
}) })
} }
} }

View File

@ -107,6 +107,11 @@ impl Package {
let bootstrap_name = format!("boot_{}", self.attrs.package_name).replace("::", "__"); let bootstrap_name = format!("boot_{}", self.attrs.package_name).replace("::", "__");
let bootstrap_ident = Ident::new(&bootstrap_name, Span::call_site()); let bootstrap_ident = Ident::new(&bootstrap_name, Span::call_site());
let boot = match &self.attrs.boot {
Some(boot) => quote! { #boot(); },
None => TokenStream::new(),
};
quote! { quote! {
#[no_mangle] #[no_mangle]
pub extern "C" fn #bootstrap_ident( pub extern "C" fn #bootstrap_ident(
@ -123,6 +128,8 @@ impl Package {
#newxs #newxs
} }
}); });
#boot
} }
} }
} }