-
Notifications
You must be signed in to change notification settings - Fork 59
Description
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 commentedon Mar 9, 2020
@tlively has made a lot of progress on the emscripten side of things, and I think can update on the status there.
tlively commentedon Mar 9, 2020
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.
Disable emscripten tests until they work again
Merge remote-tracking branch 'rust-bitcoin/master'
DzmitryFil commentedon Jun 14, 2020
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 commentedon Jun 15, 2020
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 commentedon Jun 15, 2020
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 commentedon Jun 16, 2020
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 commentedon Jun 16, 2020
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 commentedon Jun 16, 2020
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.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.
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 onimgui-rs
repo where author could chime in too and probably help out.DzmitryFil commentedon Jun 16, 2020
Yeah, i probably could successfully compile rust with emscripten, but wasm-bindgen absence seems like a showstopper.
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
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 commentedon Aug 20, 2023
@amckinney did you ever figure it out? currently struggling with rust wasm and tree-sitter
shadaj commentedon Aug 20, 2023
@vedkothavade try with https://github.com/shadaj/tree-sitter-c2rust! This is how rust-sitter supports wasm32-unknown-unknown.
kothavade commentedon Aug 20, 2023
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 commentedon Sep 8, 2023
@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 commentedon Sep 9, 2023
@shadaj thanks!
rafaelbeckel commentedon May 29, 2024
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 commentedon Dec 16, 2024
rust-lang/rust#133952 will make the correct C ABI the default.