This repository was originally created to test the state of Rust nightly for producing a compatible C ABI for the wasm32-unknown-unknown target with the flag --Z wasm_c_abi=spec.
Now Rust v1.89 officially uses the "C" ABI by default.
For context, this is the relevant tracking issue in Wasm Bingen, and the official Rust blog post talking about this.
The workspace contains a series of small examples of how to produce a single WASM binary with both C and Rust code that can call each other.
To see how to do it, check out the build.sh file in each of the crates in this workspace.
The crates experiment with different build strategies, with increasing levels of complexity:
-
- A simple calculator with primitive data types and manual build
-
- The same calculator built with the CC crate
-
- We use OpenBSD libc to implement the Mem function in the calculator and store/free a value in the heap from C with
mallocandfree
- We use OpenBSD libc to implement the Mem function in the calculator and store/free a value in the heap from C with
-
- We create a Calculator struct with member functions and export it with Wasm Bindgen
-
- This is the same as the previous project, but instead of writing the Calculator struct manually, we generate the Rust bindings from the C header with Rust Bindgen, which is the recommended way to interact with C code from Rust.
-
- This project experiments with the nightly feature
extern types.
- This project experiments with the nightly feature
To see the examples in action, use your favorite local server:
npx serveThen, visit http://localhost:3000 and click the example you want to see.
Either visit the specific crate and run its build.sh script or use the build_all.sh script in the root of the workspace to build all crates at once.
- LLVM
- Clang
- Rust (1.89 or later)
- Wasm Binary Toolkit
-
Uniffi
- I plan to add an example with Uniffi in the future.
-
Wgpu
- I have used these strategies in my work to build a
wgpuproject that depends on C libraries. I plan to bring a minimal example of it here.
- I have used these strategies in my work to build a
-
Combine different crates in a build script
- C code coming from a crate and Rust code from another, link them by using linker flags in build.rs.
-
External C libs
- Finally, let's bring an external C lib and combine all of the above.
If you'd like to see any other scenario listed here, feel free to open an Issue or a PR.
If submitting a new example, create a numbered subfolder in the crates directory following the existing structure, and ensure your example builds correctly for both WASM and unit tests.
Finally, run cargo clippy and stick with the default rules.