Skip to content

Status of rust+C bindings for wasm targets #291

@elichai

Description

@elichai

Hi,
There are a lot of important dependencies in the rust ecosystem that use ffi to C fia the cc crate or similiar.
which tools and targets currently support that?
in the past asmjs-unknown-emscripten worked and together with cargo-web you could just run cargo web test to know if your library compiles+run on wasm/emscripten.
Sadly emscripten is broken on stable for a while now rust-lang/rust#66916.

wasm32-unknown-unknown works in combination with clang-8 only(probably a bug), not before and not later(doesn't work on clang-9 and clang-10) rust-lang/cc-rs#378
so wasm-pack can't be used here.

wasi seem to have the same problem, running cargo wasi test fails to find the sysroot(fatal error: 'string.h' file not found) although it seems like you can download sysroots for wasi or compile them yourself https://bytecodealliance.github.io/wasmtime/wasm-c.html

Is there any tool out there that can test rust+C code out of the box? (We had emscripten tests in the CI until it broke and we want to continue testing for wasm target in the CI)

Activity

kripken

kripken commented on Mar 9, 2020

@kripken

@tlively has made a lot of progress on the emscripten side of things, and I think can update on the status there.

tlively

tlively commented on Mar 9, 2020

@tlively

Currently the wasm32-unknown-emscripten and asmjs-unknown-emscripten targets are the only targets that can be linked with C code because all the other wasm targets use a different ABI for compatibility with wasm-bindgen. Unfortunately, I’m the only one maintaining the emscripten targets in Rust and I don’t have a lot of time to spend on it, so I’ve mostly just been trying to fix critical bugs as I become aware of them. I’ll take a look at the one you linked to above.

added a commit that references this issue on Mar 11, 2020
added a commit that references this issue on Apr 9, 2020
DzmitryFil

DzmitryFil commented on Jun 14, 2020

@DzmitryFil

I am also struggling to compile simple c libraries like imgui to wasm.
@alexcrichton maybe you could help us, and share couple of words on how to build wasm32-unknown-unknown with wasi sysroot, or some other way? Or building rust+C to wasm is a lost cause for near future?

alexcrichton

alexcrichton commented on Jun 15, 2020

@alexcrichton
Contributor

If you want to integrate Rust and C on the web your best bet is likely going to be Emscripten. The next best bet is going to be using WASI (and wasi-sdk), but that requires getting a WASI implementation working on the best which isn't always as available. Finally you can try to get wasm32-unknown-unknown working. While that's technically possible for C/C++ there aren't really any maintained toolchains targeting that for C/C++, so you're on your own making such a toolchain.

DzmitryFil

DzmitryFil commented on Jun 15, 2020

@DzmitryFil

Well, wasm32-emscripten target doesn't get much love from rust community either. Anyway, thanks for reply, it's nice to know status of these things.

RReverser

RReverser commented on Jun 16, 2020

@RReverser
Member

Hi, I'm a WebAssembly DevRel at Google and thought I'd chime as I've actively worked with both Rust (including wasm-bindgen) and Emscripten at various points.

Admittedly, this is a simple demo, but, as far as I can tell, wasm32-unknown-emscripten target works fine for combined Rust + C code.

Of course, you can't expect to use both #[wasm_bindgen] and Emscripten bindings at the same time - you need to choose a single tool that will be providing runtime bindings and generating the JavaScript wrapper - but as long as one side is a "driver" and another contains pure portable code, things should work.

Is there a specific API or minimal code sample you could show that you're struggling with?

DzmitryFil

DzmitryFil commented on Jun 16, 2020

@DzmitryFil

Wow, thanks for offering help. My problem is compiling imgui-rs crate to wasm32-unknown-unknown target, i have no idea how to solve this, because my c++ knowledge is pretty limited.
As of emsripten, stuff like rust-lang/rust#66916 doesn't give much confidence. Also stdweb, which supports emscripten target, seems abandoned (no activity for 8 months).
Also, I do you use wasm_bindgen quite extensively. For example, how would i replace wasm-bindgen-futures crate and work with js promises from inside rust, if i choose to use wasm32-unknown-emscripten?

RReverser

RReverser commented on Jun 16, 2020

@RReverser
Member

I can't say much about cargo-web TBH because while I've seen it, personally never used it. In example above you can see that I'm just using regular cargo build command instead.

As of emsripten, stuff like rust-lang/rust#66916 doesn't give much confidence.

I haven't seen that error, and given that 1) it's from half a year ago and 2) examples I've tried work fine, I suspect it might have been some temporary issue that has been resolved since.

Also, I do you use wasm_bindgen quite extensively. For example, how would i replace wasm-bindgen-futures crate and work with js promises from inside rust, if i choose to use wasm32-unknown-emscripten?

Right, unfortunately, you can't, since these are two different toolchains. You need to either deal with Web APIs and JS values from Emscripten, or from Rust, but not both.

I've experimented in the past with using Embind in Rust (shameless plug: https://www.youtube.com/watch?v=zxIbTfsOJZE), but not too long afterwards wasm-bindgen appeared and it wasn't clear if there are benefits to using both, so never made it into a full package. Either way, if really necessary, it should be possible to build your own bindings from Rust to Emscripten's APIs or vice versa, but that would be complicated.

It might be easier to understand what issues you're running into with wasm32-unknown-unknown for your particular library, but that's probably best discussed in an issue on imgui-rs repo where author could chime in too and probably help out.

DzmitryFil

DzmitryFil commented on Jun 16, 2020

@DzmitryFil

Yeah, i probably could successfully compile rust with emscripten, but wasm-bindgen absence seems like a showstopper.

It might be easier to understand what issues you're running into with wasm32-unknown-unknown for your particular library, but that's probably best discussed in an issue on imgui-rs repo where author could chime in too and probably help out.

The thing is, my issues aren't specific to this library. When you compile any c library that uses standard headers like stdio.h or string.h you get compilation errors.
servo/rust-stb-image#94
rust-lang/cc-rs#378 (comment)
I tried manually inserting headers from wasi-libc, and including them into cc build, but then i got linking errors like

note: rust-lld: error: unable to find library -lstdc++

Imgui doesn't really need any os-specific stuff to work, i've seen it compiled with emscripten on the web, but i have no idea how to make it work with wasm32-unknown-unknown.

100 remaining items

kothavade

kothavade commented on Aug 20, 2023

@kothavade

@amckinney did you ever figure it out? currently struggling with rust wasm and tree-sitter

shadaj

shadaj commented on Aug 20, 2023

@shadaj

@vedkothavade try with https://github.com/shadaj/tree-sitter-c2rust! This is how rust-sitter supports wasm32-unknown-unknown.

kothavade

kothavade commented on Aug 20, 2023

@kothavade

thanks @shadaj! i was able to get tree-sitter-c2rust itself to build, but languages themselves fail to compile (eg. tree-sitter-c). i locally cloned the language repo and replaced the tree-sitter dep in Cargo.toml and build.rs with tree-sitter-c2rust and still am getting errors such as (stdbool.h not found) at build time--any suggestions?

edit: actually, i think that the clang errors i'm getting might be in part due to some nix weirdness going on, will have to investigate further--let me know if you've seen any CC errors when building languages though, maybe it will help

shadaj

shadaj commented on Sep 8, 2023

@shadaj

@vedkothavade sorry for the late response! Yeah, we've seen this in Rust Sitter. We get around this by including minimal stub implementations of those headers, see https://github.com/hydro-project/rust-sitter/blob/main/tool/src/lib.rs#L67.

kothavade

kothavade commented on Sep 9, 2023

@kothavade

@shadaj thanks!

rafaelbeckel

rafaelbeckel commented on May 29, 2024

@rafaelbeckel

If you arrived here while searching how to compile Rust+C for the wasm32-unknown-unknown target, it's currently possible with Rust nightly with the --Z wasm_c_abi=spec flag they introduced in April. Here's a minimal example.

bjorn3

bjorn3 commented on Dec 16, 2024

@bjorn3

rust-lang/rust#133952 will make the correct C ABI the default.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @briansmith@rafaelbeckel@Ciantic@alexcrichton@kripken

      Issue actions

        Status of rust+C bindings for wasm targets · Issue #291 · rustwasm/team