diff --git a/.cargo/config.toml b/.cargo/config.toml
index 0a2f7bfd..2f292aef 100644
--- a/.cargo/config.toml
+++ b/.cargo/config.toml
@@ -23,7 +23,7 @@ LVGL_FONTS_DIR = { value = "modules/graphics/fonts_generator/generated_fonts", r
WAMR_BUILD_PLATFORM = "XILA"
-WAMR_SHARED_PLATFORM_CONFIG = { value = "modules/virtual_machine/wamr/shared_platform.cmake", relative = true }
+WAMR_SHARED_PLATFORM_CONFIG = { value = "executables/wasm/wamr/shared_platform.cmake", relative = true }
LLVM_LIB_CFG_PATH = "/usr/lib/llvm-19/cmake/"
LITTLEFS_CONFIG = { value = "modules/little_fs/include/little_fs_config.h", relative = true }
diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index f5e2ffd3..653e0b4f 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -36,14 +36,14 @@ jobs:
- name: Check | Clippy (Host)
run: cargo make clippy-host
- - name: Check | Clippy (WASM)
- run: cargo make clippy-wasm
+ - name: Check | Clippy (Guest)
+ run: cargo make clippy-guest
- name: Check | Documentation (Host)
run: RUSTDOCFLAGS="--deny warnings" cargo make doc-host
- - name: Check | Documentation (WASM)
- run: RUSTDOCFLAGS="--deny warnings" cargo make doc-wasm
+ - name: Check | Documentation (Guest)
+ run: RUSTDOCFLAGS="--deny warnings" cargo make doc-guest
- name: Build | Example (Native)
run: cargo make build -p native_example && cargo clean -p native_example
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index 29735442..d26ce7dd 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -29,15 +29,13 @@ jobs:
run: |
cargo make doc-host
mkdir -p ./pages/host/
- cp ./documentation/index.html ./pages/host/
cp -r ./target/x86_64-unknown-linux-gnu/doc/* ./pages/host/
- - name: Build | Documentation (WASM)
+ - name: Build | Documentation (Guest)
run: |
- cargo make doc-wasm
- mkdir -p ./pages/wasm/
- cp ./documentation/index.html ./pages/wasm
- cp -r ./target/wasm32-unknown-unknown/doc/* ./pages/wasm/
+ cargo make doc-guest
+ mkdir -p ./pages/guest/
+ cp -r ./target/wasm32-unknown-unknown/doc/guest/* ./pages/guest/
- name: Build | WASM demonstration (en)
working-directory: ./examples/wasm
diff --git a/Cargo.toml b/Cargo.toml
index 0bb2ba55..4044cdb0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,15 +18,12 @@ lto = true
# - Always included
internationalization = { workspace = true }
-# - WASM
-wasm_bindings = { workspace = true, optional = true }
# - Host
abi_context = { workspace = true, optional = true }
abi_declarations = { workspace = true, optional = true }
abi_definitions = { workspace = true, optional = true }
little_fs = { workspace = true, optional = true }
-virtual_machine = { workspace = true, optional = true }
virtual_file_system = { workspace = true, optional = true }
graphics = { workspace = true, optional = true }
task = { workspace = true, optional = true }
@@ -40,16 +37,11 @@ authentication = { workspace = true, optional = true }
log = { workspace = true, optional = true }
shared = { workspace = true, optional = true }
synchronization = { workspace = true, optional = true }
-host_bindings = { workspace = true, optional = true }
bootsplash = { workspace = true, optional = true }
network = { workspace = true, optional = true }
[features]
-default = []
-
-executable_building = ["executable/building"]
-
-host = [
+default = [
"dep:abi_context",
"dep:abi_declarations",
"dep:abi_definitions",
@@ -71,23 +63,19 @@ host = [
"abi_definitions",
"dep:network",
]
+
+executable_building = ["executable/building"]
+host = []
abi_definitions = ["dep:abi_definitions"]
-virtual_machine = ["dep:virtual_machine", "dep:host_bindings"]
graphics_rendering_rgb565 = ["graphics/rendering_rgb565"]
graphics_rendering_xrgb8888 = ["graphics/rendering_xrgb8888"]
-wasm = ["dep:wasm_bindings"]
-wasm_c_bindings = ["wasm", "wasm_bindings/c_bindings"]
[workspace.dependencies]
-# - Modules
-wasm_bindings = { path = "modules/bindings/wasm" }
-
abi_context = { path = "modules/abi/context" }
abi_declarations = { path = "modules/abi/declarations" }
abi_definitions = { path = "modules/abi/definitions" }
little_fs = { path = "modules/little_fs" }
-virtual_machine = { path = "modules/virtual_machine" }
virtual_file_system = { path = "modules/virtual_file_system" }
graphics = { path = "modules/graphics" }
time = { path = "modules/time" }
@@ -96,8 +84,6 @@ users = { path = "modules/users" }
memory = { path = "modules/memory" }
executable = { path = "modules/executable" }
file_system = { path = "modules/file_system" }
-host_bindings = { path = "modules/bindings/host" }
-bindings_utilities = { path = "modules/bindings/utilities" }
authentication = { path = "modules/authentication" }
log = { path = "modules/log" }
shared = { path = "modules/shared" }
@@ -153,7 +139,6 @@ embedded-io = { version = "0.7", features = ["alloc"] }
[workspace]
members = [
"modules/file_system",
- "modules/virtual_machine",
"modules/graphics",
"modules/task",
"modules/users",
@@ -166,10 +151,6 @@ members = [
"modules/virtual_file_system",
"modules/little_fs",
"modules/target",
- "modules/bindings/utilities",
- "modules/bindings/host",
- "modules/bindings/host/tests/wasm_test",
- "modules/bindings/wasm",
"executables/file_manager",
"executables/shell/command_line",
"modules/executable",
@@ -193,7 +174,6 @@ members = [
"drivers/shared",
"drivers/std",
"drivers/wasm",
- "modules/virtual_machine/tests/wasm_test",
"modules/internationalization",
"modules/internationalization/macros",
"modules/graphics/fonts_generator",
diff --git a/Makefile.toml b/Makefile.toml
index 92fc6246..e90b4973 100644
--- a/Makefile.toml
+++ b/Makefile.toml
@@ -34,18 +34,20 @@ args = [
"--target",
"x86_64-unknown-linux-gnu",
"--features",
- "host,abi_definitions,virtual_machine,graphics_rendering_xrgb8888",
+ "host,abi_definitions,graphics_rendering_xrgb8888",
]
-[tasks.check-wasm]
+[tasks.check-guest]
toolchain = "stable"
command = "cargo"
args = [
"check",
"--target",
"wasm32-unknown-unknown",
+ "--package",
+ "wasm",
"--features",
- "wasm,wasm_c_bindings",
+ "default_guest",
]
[tasks.doc-host]
@@ -54,48 +56,58 @@ command = "cargo"
args = [
"doc",
"--features",
- "host,abi_definitions,virtual_machine,graphics_rendering_xrgb8888",
+ "host,abi_definitions,graphics_rendering_xrgb8888",
"--target",
"x86_64-unknown-linux-gnu",
]
-[tasks.doc-wasm]
+[tasks.doc-guest]
toolchain = "stable"
command = "cargo"
-args = ["doc", "--features", "wasm", "--target", "wasm32-unknown-unknown"]
+args = [
+ "doc",
+ "--package",
+ "wasm",
+ "--features",
+ "default_guest",
+ "--target",
+ "wasm32-unknown-unknown",
+]
[tasks.doc]
-dependencies = ["doc-host", "doc-wasm"]
+dependencies = ["doc-host", "doc-guest"]
[tasks.check]
-dependencies = ["check-host", "check-wasm"]
+dependencies = ["check-host", "check-guest"]
-[tasks.clippy-wasm]
+[tasks.clippy-host]
install_crate = "clippy"
toolchain = "stable"
command = "cargo"
args = [
"clippy",
"--target",
- "wasm32-unknown-unknown",
+ "x86_64-unknown-linux-gnu",
"--features",
- "wasm,wasm_c_bindings",
+ "host,abi_definitions,graphics_rendering_xrgb8888",
"--all-targets",
"--",
"-D",
"warnings",
]
-[tasks.clippy-host]
+[tasks.clippy-guest]
install_crate = "clippy"
toolchain = "stable"
command = "cargo"
args = [
"clippy",
- "--target",
- "x86_64-unknown-linux-gnu",
+ "--package",
+ "wasm",
"--features",
- "host,abi_definitions,virtual_machine,graphics_rendering_xrgb8888",
+ "default_guest",
+ "--target",
+ "wasm32-unknown-unknown",
"--all-targets",
"--",
"-D",
@@ -103,7 +115,7 @@ args = [
]
[tasks.clippy]
-dependencies = ["clippy-host", "clippy-wasm"]
+dependencies = ["clippy-host", "clippy-guest"]
[tasks.lint]
install_crate = "clippy"
diff --git a/documentation/index.html b/documentation/index.html
deleted file mode 100644
index 46d5dc03..00000000
--- a/documentation/index.html
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
- Redirecting...
-
-
-
- If you are not redirected automatically, follow this
- link.
-
-
-
diff --git a/examples/native/Cargo.toml b/examples/native/Cargo.toml
index 90981c0b..d531bd50 100644
--- a/examples/native/Cargo.toml
+++ b/examples/native/Cargo.toml
@@ -6,14 +6,13 @@ edition = "2024"
[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))'.dependencies]
xila = { path = "../../", features = [
"host",
- "virtual_machine",
"graphics_rendering_xrgb8888",
"executable_building",
] }
file_manager = { workspace = true }
command_line_shell = { workspace = true }
graphical_shell = { workspace = true }
-wasm = { workspace = true }
+wasm = { workspace = true, features = ["default_host"] }
terminal = { workspace = true }
settings = { workspace = true }
drivers_core = { workspace = true }
diff --git a/examples/native/src/main.rs b/examples/native/src/main.rs
index 1eb95156..8eaac68c 100644
--- a/examples/native/src/main.rs
+++ b/examples/native/src/main.rs
@@ -20,7 +20,6 @@ async fn main() {
use xila::file_system::mbr::Mbr;
use xila::file_system::mbr::PartitionKind;
use xila::graphics;
- use xila::host_bindings;
use xila::little_fs;
use xila::log;
use xila::network::{self, ADD_DNS_SERVER, ADD_IP_ADDRESS, ADD_ROUTE};
@@ -30,7 +29,6 @@ async fn main() {
use xila::virtual_file_system;
use xila::virtual_file_system::File;
use xila::virtual_file_system::mount_static;
- use xila::virtual_machine;
// - Initialize the system
log::initialize(&drivers_std::log::Logger).unwrap();
@@ -201,9 +199,6 @@ async fn main() {
file.close(virtual_file_system).await.unwrap();
- // Initialize the virtual machine
- virtual_machine::initialize(&[&host_bindings::GraphicsBindings]);
-
// Mount static executables
let virtual_file_system = virtual_file_system::get_instance();
diff --git a/executables/calculator/Cargo.toml b/executables/calculator/Cargo.toml
index 5447893e..a43aa040 100644
--- a/executables/calculator/Cargo.toml
+++ b/executables/calculator/Cargo.toml
@@ -4,13 +4,12 @@ version = "0.1.0"
edition = "2024"
[target.'cfg(target_arch = "wasm32")'.dependencies]
-xila = { path = "../../", features = ["wasm"] }
+wasm = { workspace = true, features = ["guest", "graphics"] }
[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))'.dev-dependencies]
xila = { path = "../../", features = [
"host",
"executable_building",
- "virtual_machine",
"graphics_rendering_xrgb8888",
] }
drivers_core = { workspace = true }
@@ -18,6 +17,7 @@ drivers_std = { workspace = true }
drivers_shared = { workspace = true }
drivers_native = { workspace = true }
testing = { workspace = true }
+wasm = { workspace = true, features = ["default_host"] }
[[test]]
name = "calculator_test"
diff --git a/executables/calculator/src/interface.rs b/executables/calculator/src/interface.rs
index b25dd4fe..d2a7357d 100644
--- a/executables/calculator/src/interface.rs
+++ b/executables/calculator/src/interface.rs
@@ -1,6 +1,6 @@
use crate::{evaluator::Evaluator, parser::Parser};
use std::{ptr::null_mut, thread::sleep};
-use xila::bindings::{
+use wasm::{
self, Color, EventCode, FlexFlow, Object, ObjectFlag, buttonmatrix_create,
buttonmatrix_get_selected_button, buttonmatrix_set_map, label_create, label_set_text,
object_add_flag, object_create, object_set_flex_flow, object_set_flex_grow, object_set_height,
@@ -117,7 +117,7 @@ const BUTTON_MAP: [*const i8; 48] = [
c"pi".as_ptr(),
c"e".as_ptr(),
c"\n".as_ptr(),
- c"".as_ptr(), // End marker
+ null_mut(), // Extra null to fill the 48-button map
];
impl ButtonIdentifier {
@@ -144,7 +144,7 @@ pub struct Interface {
}
impl Interface {
- pub fn new() -> bindings::Result {
+ pub fn new() -> wasm::Result {
let window = unsafe { Self::create_window() }?;
let (display, display_label) = unsafe { Self::create_display(window) }?;
@@ -162,7 +162,7 @@ impl Interface {
})
}
- unsafe fn create_window() -> bindings::Result<*mut Object> {
+ unsafe fn create_window() -> wasm::Result<*mut Object> {
// Create main window
unsafe {
let window = window_create()?;
@@ -183,7 +183,7 @@ impl Interface {
}
}
- unsafe fn create_display(window: *mut Object) -> bindings::Result<(*mut Object, *mut Object)> {
+ unsafe fn create_display(window: *mut Object) -> wasm::Result<(*mut Object, *mut Object)> {
unsafe {
// Create display container using generic object create
let display = object_create(window)?;
@@ -204,7 +204,7 @@ impl Interface {
}
}
- unsafe fn create_button_matrix(window: *mut Object) -> bindings::Result<*mut Object> {
+ unsafe fn create_button_matrix(window: *mut Object) -> wasm::Result<*mut Object> {
// Create button matrix for calculator
unsafe {
let button_matrix = buttonmatrix_create(window)?;
@@ -223,7 +223,7 @@ impl Interface {
// Define button layout - Extended scientific calculator
// Set the button map
- buttonmatrix_set_map(button_matrix as u16, BUTTON_MAP.as_ptr())?;
+ buttonmatrix_set_map(button_matrix, BUTTON_MAP.as_ptr())?;
// Optional: Make some buttons wider if needed
// buttonmatrix_set_button_width(self.button_matrix, 31, 2); // Make "0" wider
@@ -232,7 +232,7 @@ impl Interface {
}
}
- fn update_display(&mut self) -> bindings::Result<()> {
+ fn update_display(&mut self) -> wasm::Result<()> {
unsafe {
let display_text = if self.show_result {
self.current_expression.clone()
@@ -257,7 +257,7 @@ impl Interface {
Ok(())
}
- unsafe fn handle_button_matrix_event(&mut self) -> bindings::Result<()> {
+ unsafe fn handle_button_matrix_event(&mut self) -> wasm::Result<()> {
// Get the selected button ID from the button matrix
let selected_button_id: u32 =
unsafe { buttonmatrix_get_selected_button(self.button_matrix) }?;
@@ -269,7 +269,7 @@ impl Interface {
Ok(())
}
- fn handle_button_press(&mut self, button: ButtonIdentifier) -> bindings::Result<()> {
+ fn handle_button_press(&mut self, button: ButtonIdentifier) -> wasm::Result<()> {
match button {
ButtonIdentifier::Clear => {
self.current_expression.clear();
diff --git a/executables/calculator/tests/test.rs b/executables/calculator/tests/test.rs
index 1123071a..70ad32a2 100644
--- a/executables/calculator/tests/test.rs
+++ b/executables/calculator/tests/test.rs
@@ -1,52 +1,67 @@
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
#[xila::task::test(task_path = xila::task)]
-#[ignore]
+#[ignore = "This test is meant to be run interactively"]
async fn main() {
drivers_std::memory::instantiate_global_allocator!();
extern crate alloc;
- use drivers_std::executor::new_thread_executor;
- use std::fs;
- use xila::executable::build_crate;
- use xila::host_bindings;
+ use drivers_std::loader::load_to_virtual_file_system;
+ use wasm::WasmExecutable;
+ use xila::executable;
+ use xila::executable::{build_crate, mount_executables};
use xila::task;
- use xila::time::Duration;
- use xila::virtual_machine;
-
- let binary_path = build_crate("calculator").unwrap();
- let binary_buffer = fs::read(binary_path).unwrap();
-
- let standard = testing::initialize(true, false).await.split();
-
- let task_manager = task::get_instance();
- let virtual_machine = virtual_machine::initialize(&[&host_bindings::GraphicsBindings]);
-
- let additional_spawner = new_thread_executor().await;
-
- task_manager
- .spawn(
- task_manager.get_current_task_identifier().await,
- "Runner",
- Some(additional_spawner),
- async move |task| {
- virtual_machine
- .execute(
- binary_buffer.to_vec(),
- 8 * 1024,
- standard,
- None,
- vec![],
- task,
- )
- .await
- .unwrap();
- },
- )
- .await
- .unwrap();
-
- loop {
- task::Manager::sleep(Duration::from_millis(1000)).await;
+ use xila::virtual_file_system;
+
+ let standard = testing::initialize(true, false).await;
+
+ let virtual_file_system = virtual_file_system::get_instance();
+ let task_instance = task::get_instance();
+ let task = task_instance.get_current_task_identifier().await;
+
+ let binary_path = build_crate(&"calculator").unwrap();
+ load_to_virtual_file_system(
+ virtual_file_system,
+ binary_path,
+ "/binaries/calculator.wasm",
+ )
+ .await
+ .unwrap();
+
+ fn new_thread_executor_wrapper()
+ -> core::pin::Pin + Send>> {
+ use drivers_std::executor::new_thread_executor;
+
+ Box::pin(new_thread_executor())
}
+
+ mount_executables!(
+ virtual_file_system,
+ task,
+ &[(
+ "/binaries/wasm",
+ WasmExecutable::new(Some(new_thread_executor_wrapper))
+ )]
+ )
+ .await
+ .unwrap();
+
+ let result = executable::execute(
+ "/binaries/wasm",
+ vec!["/binaries/calculator.wasm".to_string()],
+ standard,
+ None,
+ )
+ .await
+ .unwrap()
+ .join()
+ .await;
+
+ // let result = executable::execute("/binaries/command_line_shell", vec![], standard, None)
+ // .await
+ // .unwrap()
+ // .join()
+ // .await;
+
+ assert!(result == 0);
}
diff --git a/executables/wasm/Cargo.toml b/executables/wasm/Cargo.toml
index 91befdeb..013e6ef7 100644
--- a/executables/wasm/Cargo.toml
+++ b/executables/wasm/Cargo.toml
@@ -2,9 +2,33 @@
name = "wasm"
version = "0.1.0"
edition = "2024"
+build = "build/main.rs"
[dependencies]
-xila = { path = "../../", features = ["host", "virtual_machine"] }
+xila = { path = "../../", optional = true }
+wamr-rust-sdk = { git = "https://github.com/bytecodealliance/wamr-rust-sdk.git", features = [
+ "multi-module",
+], optional = true }
+
+[features]
+default = []
+graphics = []
+c_bindings = []
+host = ["dep:xila", "dep:wamr-rust-sdk"]
+guest = []
+wasm32 = []
+wasm64 = []
+default_host = ["host", "graphics", "wasm32"]
+default_guest = ["guest", "graphics", "c_bindings"]
+
+[build-dependencies]
+lvgl_rust_sys = { git = "https://github.com/Xila-Project/lvgl_rust_sys.git", default-features = false }
+bindgen = { workspace = true }
+quote = { workspace = true }
+syn = { workspace = true, features = ["full", "visit", "extra-traits"] }
+target = { workspace = true }
+proc-macro2 = { workspace = true }
+cbindgen = { workspace = true }
[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))'.dev-dependencies]
drivers_native = { workspace = true }
diff --git a/modules/bindings/wasm/build/generator.rs b/executables/wasm/build/guest.rs
similarity index 66%
rename from modules/bindings/wasm/build/generator.rs
rename to executables/wasm/build/guest.rs
index 5ad89573..ad9d447d 100644
--- a/modules/bindings/wasm/build/generator.rs
+++ b/executables/wasm/build/guest.rs
@@ -1,14 +1,16 @@
use std::ops::Deref;
-use std::path::Path;
-
-use bindings_utilities::enumeration;
-use bindings_utilities::file::write_token_stream_to_file;
-use bindings_utilities::format::snake_to_upper_camel_case;
-
-use bindings_utilities::context::LvglContext;
-use bindings_utilities::function::{get_function_identifier, is_public_input};
+use std::path::{Path, PathBuf};
+use std::{env, fs};
+
+use crate::utilities::context::LvglContext;
+use crate::utilities::file::write_token_stream_to_file;
+use crate::utilities::format::{format_rust, snake_to_upper_camel_case};
+use crate::utilities::function::{get_function_identifier, is_public_input};
+use crate::utilities::{self, enumeration};
+use cbindgen::{EnumConfig, ExportConfig, FunctionConfig, RenameRule};
use proc_macro2::TokenStream;
use quote::{ToTokens, format_ident, quote};
+use syn::visit::Visit;
use syn::{FnArg, Ident, ReturnType, Signature, Type};
fn convert_type(mut ty: Type) -> Type {
@@ -21,6 +23,7 @@ fn convert_type(mut ty: Type) -> Type {
"lv_obj_flag_t" => format_ident!("ObjectFlag"),
"lv_obj_point_transform_flag_t" => format_ident!("ObjectPointTransformFlag"),
"lv_result_t" => format_ident!("LvglResult"),
+ "WasmPointer" => format_ident!("c_void"),
identifier => {
let ident = if identifier.starts_with("lv_") {
let ident = identifier.strip_prefix("lv_").unwrap_or(identifier);
@@ -126,7 +129,7 @@ fn generate_xila_graphics_call(signature: &Signature) -> TokenStream {
quote! {
xila_graphics_call(
- crate::FunctionCall::#enumeration_variant,
+ FunctionCall::#enumeration_variant,
#( #passed_arguments ),*,
#argument_count,
#passed_result
@@ -226,7 +229,7 @@ fn generate_function(signature: &Signature) -> TokenStream {
}
}
-pub fn generate_enumeration(
+fn generate_enumeration(
path: impl AsRef,
lvgl_functions: &LvglContext,
) -> Result<(), String> {
@@ -237,10 +240,7 @@ pub fn generate_enumeration(
Ok(())
}
-pub fn generate_functions(
- path: impl AsRef,
- lvgl_functions: &LvglContext,
-) -> Result<(), String> {
+fn generate_functions(path: impl AsRef, lvgl_functions: &LvglContext) -> Result<(), String> {
let generated_functions = lvgl_functions
.get_signatures()
.iter()
@@ -258,7 +258,7 @@ pub fn generate_functions(
Ok(())
}
-pub fn generate_c_abi_functions(
+fn generate_c_abi_functions(
path: impl AsRef,
lvgl_functions: &LvglContext,
) -> Result<(), String> {
@@ -274,7 +274,97 @@ pub fn generate_c_abi_functions(
#( #generated_c_abi_functions )*
};
+ println!(
+ "cargo:warning=Generating C ABI functions at path: {}",
+ path.as_ref().display()
+ );
+
write_token_stream_to_file(path, token_stream)?;
Ok(())
}
+
+fn is_c_bindings_enabled() -> bool {
+ env::var_os("CARGO_FEATURE_C_BINDINGS").is_some()
+}
+
+fn generate_c_functions_module_body(path: impl AsRef) -> Result<(), String> {
+ let token_stream = quote! {
+ include!(concat!(env!("OUT_DIR"), "/c_functions.generated.rs"));
+ };
+
+ fs::write(&path, token_stream.to_string())
+ .map_err(|e| format!("Error writing to file: {}", e))?;
+
+ format_rust(path)?;
+
+ Ok(())
+}
+
+pub fn generate(output_path: &Path) {
+ let input = lvgl_rust_sys::_bindgen_raw_src();
+ let parsed_input = syn::parse_file(input).expect("Error parsing input file");
+
+ let mut context = LvglContext::default();
+ context.set_function_filtering(Some(LvglContext::filter_function));
+ context.visit_file(&parsed_input);
+ context.set_function_filtering(None);
+ context.visit_file(&syn::parse2(utilities::additional::get()).unwrap());
+
+ let crate_directory = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
+
+ let enumerations_generated_path = output_path.join("enumeration.generated.rs");
+ let functions_generated_path = output_path.join("functions.generated.rs");
+ let c_functions_generated_path = output_path.join("c_functions.generated.rs");
+ let c_functions_module_path = crate_directory
+ .join("src")
+ .join("guest")
+ .join("graphics")
+ .join("c_functions.rs");
+ let c_header_path = output_path.join("xila_graphics.h");
+
+ generate_enumeration(&enumerations_generated_path, &context).unwrap();
+
+ generate_functions(&functions_generated_path, &context).unwrap();
+
+ if is_c_bindings_enabled() {
+ // Overwrite c_functions.rs file with generated C ABI functions
+ // This is workaround for cbindgen macro expansion limitations
+ generate_c_abi_functions(&c_functions_module_path, &context).unwrap();
+
+ generate_c_abi_functions(&c_functions_generated_path, &context).unwrap();
+
+ let configuration: cbindgen::Config = cbindgen::Config {
+ language: cbindgen::Language::C,
+ include_guard: Some("__XILA_GRAPHICS_GENERATED_H_INCLUDED".to_string()),
+ sys_includes: vec![
+ "stdarg.h".to_string(),
+ "stdbool.h".to_string(),
+ "stdint.h".to_string(),
+ ],
+ export: ExportConfig {
+ prefix: Some("XilaGraphics".to_string()),
+ ..Default::default()
+ },
+ function: FunctionConfig {
+ ..Default::default()
+ },
+ no_includes: true,
+ enumeration: EnumConfig {
+ rename_variants: RenameRule::QualifiedScreamingSnakeCase,
+ ..Default::default()
+ },
+ ..Default::default()
+ };
+
+ cbindgen::Builder::new()
+ .with_crate(crate_directory)
+ .with_config(configuration)
+ .generate()
+ .expect("Unable to generate bindings")
+ .write_to_file(&c_header_path);
+
+ // Restore c_functions.rs file
+ generate_c_functions_module_body(&c_functions_module_path).unwrap();
+ }
+}
diff --git a/executables/wasm/build/host.rs b/executables/wasm/build/host.rs
new file mode 100644
index 00000000..cb3622c2
--- /dev/null
+++ b/executables/wasm/build/host.rs
@@ -0,0 +1,206 @@
+use crate::utilities::{
+ self, context::LvglContext, enumeration, file::write_token_stream_to_file,
+ function::split_inputs,
+};
+use std::path::Path;
+
+use proc_macro2::{Literal, TokenStream};
+use quote::{ToTokens, format_ident, quote};
+use syn::{FnArg, ItemFn, ReturnType, Signature, visit::Visit};
+
+fn generate_conversion_for_output(r#return: &ReturnType) -> Result