linker.rs 1.3 KB

12345678910111213141516171819202122232425
  1. use proc_macro2::TokenStream as TokenStream2;
  2. use quote::ToTokens;
  3. /// We store description of the assets an application uses in the executable.
  4. /// We use the `link_section` attribute embed an extra section in the executable.
  5. /// We force rust to store a serialized representation of the asset description
  6. /// inside a particular region of the binary, with the label "manganis".
  7. /// After linking, the "manganis" sections of the different object files will be merged.
  8. pub fn generate_link_section(asset: impl ToTokens, asset_hash: &str) -> TokenStream2 {
  9. let position = proc_macro2::Span::call_site();
  10. let export_name = syn::LitStr::new(&format!("__MANGANIS__{}", asset_hash), position);
  11. quote::quote! {
  12. // First serialize the asset into a constant sized buffer
  13. const __BUFFER: manganis::macro_helpers::const_serialize::ConstVec<u8> = manganis::macro_helpers::serialize_asset(&#asset);
  14. // Then pull out the byte slice
  15. const __BYTES: &[u8] = __BUFFER.as_ref();
  16. // And the length of the byte slice
  17. const __LEN: usize = __BYTES.len();
  18. // Now that we have the size of the asset, copy the bytes into a static array
  19. #[unsafe(export_name = #export_name)]
  20. static __LINK_SECTION: [u8; __LEN] = manganis::macro_helpers::copy_bytes(__BYTES);
  21. }
  22. }