diff --git a/language-bindings/rust/Cargo.toml b/language-bindings/rust/Cargo.toml index 4b2ab6138e..95a4564aba 100644 --- a/language-bindings/rust/Cargo.toml +++ b/language-bindings/rust/Cargo.toml @@ -6,10 +6,14 @@ name = "wamr-rust-sdk" version = "0.1.0" edition = "2021" license = "Apache-2.0 WITH LLVM-exception" +resolver = "2" [dependencies] wamr-sys = { path = "crates/wamr-sys", version = "0.1.0" } [workspace] -members = ["crates/wamr-sys"] -exclude = ["examples/wasi-hello", "resources/test/hello"] +members = ["crates/wamr-sys", ] +exclude = ["examples/wasi-hello", "resources/test/gcd", "resources/test/add-extra"] + +[features] +llvmjit = ["wamr-sys/llvmjit"] diff --git a/language-bindings/rust/crates/wamr-sys/Cargo.toml b/language-bindings/rust/crates/wamr-sys/Cargo.toml index 002db49699..e071d39d1b 100644 --- a/language-bindings/rust/crates/wamr-sys/Cargo.toml +++ b/language-bindings/rust/crates/wamr-sys/Cargo.toml @@ -7,6 +7,7 @@ version = "0.1.0" edition = "2021" license = "Apache-2.0 WITH LLVM-exception" authors = ["Sven Pfennig "] +links = "vmlib" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -16,3 +17,6 @@ authors = ["Sven Pfennig "] cc = "1.0" cmake = "0.1" bindgen = "0.66" + +[features] +llvmjit = [] diff --git a/language-bindings/rust/crates/wamr-sys/build.rs b/language-bindings/rust/crates/wamr-sys/build.rs index 26bc2feb58..c1fd231ff2 100644 --- a/language-bindings/rust/crates/wamr-sys/build.rs +++ b/language-bindings/rust/crates/wamr-sys/build.rs @@ -7,17 +7,22 @@ extern crate bindgen; extern crate cmake; use cmake::Config; -use std::{env, path::PathBuf}; +use std::{env, path::Path, path::PathBuf}; fn main() { - let wamr_root = "../../../../"; - let llvm_dir = format!("{wamr_root}core/deps/llvm/build"); - let dst = Config::new(wamr_root) - .define("LLVM_DIR", llvm_dir) + let wamr_root = Path::new("../../../../").canonicalize().unwrap(); + assert!(wamr_root.exists()); + + let llvm_dir = wamr_root.join("core/deps/llvm/build"); + assert!(llvm_dir.exists()); + + let enable_llvm_jit = if cfg!(feature = "llvmjit") { "1" } else { "0" }; + let dst = Config::new(&wamr_root) // running mode + .define("WAMR_BUILD_AOT", "1") .define("WAMR_BUILD_INTERP", "1") .define("WAMR_BUILD_FAST_INTERP", "1") - // .define("WAMR_BUILD_JIT", "1") + .define("WAMR_BUILD_JIT", enable_llvm_jit) // mvp .define("WAMR_BUILD_BULK_MEMORY", "1") .define("WAMR_BUILD_REF_TYPES", "1") @@ -26,19 +31,103 @@ fn main() { .define("WAMR_BUILD_LIBC_WASI", "1") // `nostdlib` .define("WAMR_BUILD_LIBC_BUILTIN", "1") + .build_target("iwasm_static") .build(); - println!( - "cargo:rustc-link-search=native={}", - dst.join("build").display() - ); - println!("cargo:rustc-link-lib=vmlib"); + println!("cargo:rustc-link-search=native={}/build", dst.display()); + println!("cargo:rustc-link-lib=static=vmlib"); + + // //TODO: support macos? + if cfg!(feature = "llvmjit") { + println!("cargo:rustc-link-lib=dylib=dl"); + println!("cargo:rustc-link-lib=dylib=m"); + println!("cargo:rustc-link-lib=dylib=rt"); + println!("cargo:rustc-link-lib=dylib=stdc++"); + println!("cargo:rustc-link-lib=dylib=z"); + + println!("cargo:libdir={}/lib", llvm_dir.display()); + println!("cargo:rustc-link-search=native={}/lib", llvm_dir.display()); + println!("cargo:rustc-link-lib=static=LLVMXRay"); + println!("cargo:rustc-link-lib=static=LLVMLibDriver"); + println!("cargo:rustc-link-lib=static=LLVMDlltoolDriver"); + println!("cargo:rustc-link-lib=static=LLVMCoverage"); + println!("cargo:rustc-link-lib=static=LLVMLineEditor"); + println!("cargo:rustc-link-lib=static=LLVMX86Disassembler"); + println!("cargo:rustc-link-lib=static=LLVMX86AsmParser"); + println!("cargo:rustc-link-lib=static=LLVMX86CodeGen"); + println!("cargo:rustc-link-lib=static=LLVMX86Desc"); + println!("cargo:rustc-link-lib=static=LLVMX86Info"); + println!("cargo:rustc-link-lib=static=LLVMOrcJIT"); + println!("cargo:rustc-link-lib=static=LLVMMCJIT"); + println!("cargo:rustc-link-lib=static=LLVMJITLink"); + println!("cargo:rustc-link-lib=static=LLVMInterpreter"); + println!("cargo:rustc-link-lib=static=LLVMExecutionEngine"); + println!("cargo:rustc-link-lib=static=LLVMRuntimeDyld"); + println!("cargo:rustc-link-lib=static=LLVMOrcTargetProcess"); + println!("cargo:rustc-link-lib=static=LLVMOrcShared"); + println!("cargo:rustc-link-lib=static=LLVMDWP"); + println!("cargo:rustc-link-lib=static=LLVMSymbolize"); + println!("cargo:rustc-link-lib=static=LLVMDebugInfoPDB"); + println!("cargo:rustc-link-lib=static=LLVMDebugInfoGSYM"); + println!("cargo:rustc-link-lib=static=LLVMOption"); + println!("cargo:rustc-link-lib=static=LLVMObjectYAML"); + println!("cargo:rustc-link-lib=static=LLVMMCA"); + println!("cargo:rustc-link-lib=static=LLVMMCDisassembler"); + println!("cargo:rustc-link-lib=static=LLVMLTO"); + println!("cargo:rustc-link-lib=static=LLVMPasses"); + println!("cargo:rustc-link-lib=static=LLVMCFGuard"); + println!("cargo:rustc-link-lib=static=LLVMCoroutines"); + println!("cargo:rustc-link-lib=static=LLVMObjCARCOpts"); + println!("cargo:rustc-link-lib=static=LLVMipo"); + println!("cargo:rustc-link-lib=static=LLVMVectorize"); + println!("cargo:rustc-link-lib=static=LLVMLinker"); + println!("cargo:rustc-link-lib=static=LLVMInstrumentation"); + println!("cargo:rustc-link-lib=static=LLVMFrontendOpenMP"); + println!("cargo:rustc-link-lib=static=LLVMFrontendOpenACC"); + println!("cargo:rustc-link-lib=static=LLVMExtensions"); + println!("cargo:rustc-link-lib=static=LLVMDWARFLinker"); + println!("cargo:rustc-link-lib=static=LLVMGlobalISel"); + println!("cargo:rustc-link-lib=static=LLVMMIRParser"); + println!("cargo:rustc-link-lib=static=LLVMAsmPrinter"); + println!("cargo:rustc-link-lib=static=LLVMDebugInfoMSF"); + println!("cargo:rustc-link-lib=static=LLVMDebugInfoDWARF"); + println!("cargo:rustc-link-lib=static=LLVMSelectionDAG"); + println!("cargo:rustc-link-lib=static=LLVMCodeGen"); + println!("cargo:rustc-link-lib=static=LLVMIRReader"); + println!("cargo:rustc-link-lib=static=LLVMAsmParser"); + println!("cargo:rustc-link-lib=static=LLVMInterfaceStub"); + println!("cargo:rustc-link-lib=static=LLVMFileCheck"); + println!("cargo:rustc-link-lib=static=LLVMFuzzMutate"); + println!("cargo:rustc-link-lib=static=LLVMTarget"); + println!("cargo:rustc-link-lib=static=LLVMScalarOpts"); + println!("cargo:rustc-link-lib=static=LLVMInstCombine"); + println!("cargo:rustc-link-lib=static=LLVMAggressiveInstCombine"); + println!("cargo:rustc-link-lib=static=LLVMTransformUtils"); + println!("cargo:rustc-link-lib=static=LLVMBitWriter"); + println!("cargo:rustc-link-lib=static=LLVMAnalysis"); + println!("cargo:rustc-link-lib=static=LLVMProfileData"); + println!("cargo:rustc-link-lib=static=LLVMObject"); + println!("cargo:rustc-link-lib=static=LLVMTextAPI"); + println!("cargo:rustc-link-lib=static=LLVMMCParser"); + println!("cargo:rustc-link-lib=static=LLVMMC"); + println!("cargo:rustc-link-lib=static=LLVMDebugInfoCodeView"); + println!("cargo:rustc-link-lib=static=LLVMBitReader"); + println!("cargo:rustc-link-lib=static=LLVMCore"); + println!("cargo:rustc-link-lib=static=LLVMRemarks"); + println!("cargo:rustc-link-lib=static=LLVMBitstreamReader"); + println!("cargo:rustc-link-lib=static=LLVMBinaryFormat"); + println!("cargo:rustc-link-lib=static=LLVMTableGen"); + println!("cargo:rustc-link-lib=static=LLVMSupport"); + println!("cargo:rustc-link-lib=static=LLVMDemangle"); + } + + let wamr_header = wamr_root.join("core/iwasm/include/wasm_export.h"); + assert!(wamr_header.exists()); - let wamr_header = format!("{wamr_root}core/iwasm/include/wasm_export.h"); let bindings = bindgen::Builder::default() .ctypes_prefix("::core::ffi") .use_core() - .header(wamr_header) + .header(wamr_header.into_os_string().into_string().unwrap()) .derive_default(true) .generate() .expect("Unable to generate bindings"); diff --git a/language-bindings/rust/resources/test/add-extra/Cargo.lock b/language-bindings/rust/resources/test/add-extra/Cargo.lock new file mode 100644 index 0000000000..dad10c93ed --- /dev/null +++ b/language-bindings/rust/resources/test/add-extra/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "add_extra" +version = "0.1.0" diff --git a/language-bindings/rust/resources/test/add-extra/Cargo.toml b/language-bindings/rust/resources/test/add-extra/Cargo.toml new file mode 100644 index 0000000000..c0ca5e86a0 --- /dev/null +++ b/language-bindings/rust/resources/test/add-extra/Cargo.toml @@ -0,0 +1,11 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +[package] +name = "add_extra" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/language-bindings/rust/resources/test/add-extra/src/main.rs b/language-bindings/rust/resources/test/add-extra/src/main.rs new file mode 100644 index 0000000000..64071bd965 --- /dev/null +++ b/language-bindings/rust/resources/test/add-extra/src/main.rs @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#[link(wasm_import_module = "host")] +extern "C" { + fn extra() -> u32; +} + +#[export_name = "add"] +pub fn add_ex(m: u32, n: u32) -> u32 { + m + n + unsafe { extra() } +} + +fn main() { + println!("Hello, world! Please call add(10, 20) to see the result."); +} diff --git a/language-bindings/rust/resources/test/add_extra_wasm32_wasi.wasm b/language-bindings/rust/resources/test/add_extra_wasm32_wasi.wasm new file mode 100755 index 0000000000..5c701a20d3 Binary files /dev/null and b/language-bindings/rust/resources/test/add_extra_wasm32_wasi.wasm differ diff --git a/language-bindings/rust/resources/test/gcd/src/main.rs b/language-bindings/rust/resources/test/gcd/src/main.rs index a83a8226a5..d4f190df85 100644 --- a/language-bindings/rust/resources/test/gcd/src/main.rs +++ b/language-bindings/rust/resources/test/gcd/src/main.rs @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception */ -#[no_mangle] +#[export_name = "gcd"] pub fn gcd(m: u32, n: u32) -> u32 { let mut a = m; let mut b = n; diff --git a/language-bindings/rust/resources/test/gcd_wasm32_wasi.wasm b/language-bindings/rust/resources/test/gcd_wasm32_wasi.wasm index 04e8cfcd62..583d166635 100755 Binary files a/language-bindings/rust/resources/test/gcd_wasm32_wasi.wasm and b/language-bindings/rust/resources/test/gcd_wasm32_wasi.wasm differ diff --git a/language-bindings/rust/src/runtime.rs b/language-bindings/rust/src/runtime.rs index c1a63f06e5..11b344c45b 100644 --- a/language-bindings/rust/src/runtime.rs +++ b/language-bindings/rust/src/runtime.rs @@ -13,8 +13,8 @@ use std::sync::{Arc, OnceLock}; use wamr_sys::{ mem_alloc_type_t_Alloc_With_Pool, mem_alloc_type_t_Alloc_With_System_Allocator, - wasm_runtime_destroy, wasm_runtime_full_init, wasm_runtime_init, RunningMode_Mode_Fast_JIT, - RunningMode_Mode_Interp, RunningMode_Mode_LLVM_JIT, RuntimeInitArgs, + wasm_runtime_destroy, wasm_runtime_full_init, wasm_runtime_init, RunningMode_Mode_Interp, + RunningMode_Mode_LLVM_JIT, RuntimeInitArgs, }; use crate::RuntimeError; @@ -43,22 +43,14 @@ impl RuntimeBuilder { self } - //TODO: feature /// use interpreter mode pub fn run_as_interpreter(mut self) -> RuntimeBuilder { self.args.running_mode = RunningMode_Mode_Interp; self } - //TODO: feature - /// use fast-jit mode - pub fn run_as_fast_jit(mut self, code_cache_size: u32) -> RuntimeBuilder { - self.args.running_mode = RunningMode_Mode_Fast_JIT; - self.args.fast_jit_code_cache_size = code_cache_size; - self - } + /// TODO: use fast-jit mode - //TODO: feature /// use llvm-jit mode pub fn run_as_llvm_jit(mut self, opt_level: u32, size_level: u32) -> RuntimeBuilder { self.args.running_mode = RunningMode_Mode_LLVM_JIT; @@ -145,6 +137,7 @@ impl Drop for Runtime { #[cfg(test)] mod tests { use super::*; + use wamr_sys::{wasm_runtime_free, wasm_runtime_malloc}; #[test] fn test_runtime_new() { @@ -164,13 +157,22 @@ mod tests { let runtime = Runtime::new(); assert!(runtime.is_ok()); } + + let small_buf = unsafe { wasm_runtime_malloc(16) }; + assert!(!small_buf.is_null()); + unsafe { wasm_runtime_free(small_buf) }; } #[test] fn test_runtime_builder_default() { + // use Mode_Default let runtime = Runtime::builder().use_system_allocator().build(); assert!(runtime.is_ok()); drop(runtime); + + let small_buf = unsafe { wasm_runtime_malloc(16) }; + assert!(!small_buf.is_null()); + unsafe { wasm_runtime_free(small_buf) }; } #[test] @@ -181,16 +183,10 @@ mod tests { .build(); assert!(runtime.is_ok()); drop(runtime); - } - #[test] - fn test_runtime_builder_fast_jit() { - let runtime = Runtime::builder() - .run_as_fast_jit(1024) - .use_system_allocator() - .build(); - assert!(runtime.is_ok()); - drop(runtime); + let small_buf = unsafe { wasm_runtime_malloc(16) }; + assert!(!small_buf.is_null()); + unsafe { wasm_runtime_free(small_buf) }; } #[test] @@ -201,5 +197,9 @@ mod tests { .build(); assert!(runtime.is_ok()); drop(runtime); + + let small_buf = unsafe { wasm_runtime_malloc(16) }; + assert!(!small_buf.is_null()); + unsafe { wasm_runtime_free(small_buf) }; } }