Rafael Beckel
Rafael Beckel

Reputation: 2504

How you can link a Rust library with C/C++ and wasm-bindgen for the wasm32-unknown-unknown target?

Title.

What are the specific steps to compile and link C/C++ and Rust under the same WASM binary for wasm32-unknown-unknown while using wasm-bindgen?

Context

Problem

The Rust compiler used to produce an incompatible C ABI for the wasm32-unknown-unknown target, that does not follow the specs-compliant clang's C ABI.

As wasm-bindgen depends on the Rust compiler, it also produced a WASM binary that was fundamentally incompatible and could not be linked together with binaries created by compliant C compilers.

Current State of the Ecosystem

There has been significant progress towards a solution. In April 2024, the Rust compiler team introduced a perma-unstable --wasm_c_abi flag that tells the compiler to produce compliant C ABI for WASM targets, and wasm-bindgen started to support compliant C ABI starting from version 0.2.88. This is the relevant tracking issue.

This flag is available in nightly Rust and will be removed in a future version, where the compiler will produce compliant C ABI by default.

Upvotes: 2

Views: 807

Answers (1)

Rafael Beckel
Rafael Beckel

Reputation: 2504

Up until April 2024, you needed to use wasm32-unknown-emscripten or wasm32-wasi targets to link C and Rust under the same binary.

Now that the Rust compiler team Merged a PR introducing the perma-unstable wasm_c_abi flag, it's now possible to compile Rust+C for the wasm32-unknown-unknown target with Rust nightly and use wasm-bindgen with external C dependencies. This will be the default behavior in the near future.

Here's a minimal example of a Rust+C WASM lib.

The build process boils down to:

export RUSTFLAGS="--cfg=web_sys_unstable_apis --Z wasm_c_abi=spec"
cargo +nightly build --target=wasm32-unknown-unknown --release

cp target/wasm32-unknown-unknown/release/hello.rlib hello.a

clang \
    --target=wasm32 \
    -c \
    -o world.o \
    world.c

wasm-ld \
    --no-entry \
    --export-all \
    -o hello_world.wasm \
    hello.a \
    world.o

Upvotes: 2

Related Questions