The Rust reference states:
A dynamic system library will be produced. This is used when compiling a dynamic library to be loaded from another language. This output type will create
*.so
files on Linux,*.dylib
files on macOS, and*.dll
files on Windows.
My WASM is not a *.dylib
, *.dll
, or *.so
... so why must the crate type be set to cdylib? What is really happening under the hood?
lib.rs
#[no_mangle]
pub extern fn add_one(x: u32) -> u32 {
x + 1
}
Cargo.toml
[package]
name = "utils"
version = "0.1.0"
authors = [""]
edition = "2018"
[dependencies]
[lib]
crate-type = ["cdylib"] // Why is this needed
index.html:
<!DOCTYPE html>
<html>
<head>
<script>
fetch("utils.gc.wasm")
.then(response => response.arrayBuffer())
.then(result => WebAssembly.instantiate(result))
.then(wasmModule => {
const result = wasmModule.instance.exports.add_one(2);
const text = document.createTextNode(result);
document.body.appendChild(text);
});
</script>
<head>
<body></body>
<html>
Terminal:
$ cd utils
$ cargo build --target wasm32-unknown-unknown --release
$ wasm-gc target/wasm32-unknown-unknown/release/utils.wasm -o utils.gc.wasm
$ http
It is exactly as the Rust reference states: We are creating a dynamic library to be loaded from another language. So why is the output neither .dll
, .so
or .dylib
? That is because we are not compiling for either Windows, Linux or MacOS. We are compiling for wasm32-unknown-unknown
. So the only shortcoming of the reference here is not listing all possible platforms and their dynamic library file endings.
We need a dynamic library, because dynamic libraries can be loaded at runtime (typically by the browser). Rust libraries have to be statically linked to be used.
An extra tidbit of information of what is going on under the hood:
If you invoke the wasm_bindgen
macro it will (among other things) expand the signature of a function into a C
function.
#[wasm_bindgen]
pub fn my_function()
#[export_name = "my_function"]
pub extern "C" fn __wasm_bindgen_my_function()
Why a C Function? Function calls can differ from language to language. By mangling, order of the arguments on the callstack, etc. . This is called the ABI. C
has the distinct advantage of having a defined and stable ABI, which is why it is a popular choice for foreign function interfaces.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With