Stream: wasm

Topic: Link wasm32-wasi into wasm-bindgen project


view this post on Zulip Dominic Elm (Aug 16 2023 at 17:43):

Is it possible to link a C++ project compiled to wasm32-wasi into a Rust crate that uses wasm-bindgen and compiles to wasm32-unknown-unknown?

view this post on Zulip bjorn3 (Aug 16 2023 at 19:23):

In rust due to historic accident wasm32-unknown-unknown is ABI incompatible with the wasm C ABI that rustc uses for wasm32-wasi and clang uses for all wasm targets. So if you want to directly call C++ functions from the rust crate, that isn't going to work. If you only work through the wasi interface it could work, but you did have to write a wasi implementation in rust and link the C++ code as static library. You can't link an already linked wasm module with other code.

view this post on Zulip Dominic Elm (Aug 17 2023 at 07:27):

Oh interesting, that's unfortunate. Thanks for the reply. What I Was trying to do is to link a C++ project (URL parser) into a Rust crate but that C++ project requires some libc functionality.

view this post on Zulip Dominic Elm (Aug 17 2023 at 07:27):

Tho it's not really relying on any syscalls, so I am wondering if I could somehow mock the syscalls and compile it to wasm32-unknown-unknown :thinking:

view this post on Zulip Dominic Elm (Aug 17 2023 at 07:27):

Would that be possible @bjorn3?

view this post on Zulip bjorn3 (Aug 17 2023 at 08:49):

If you only pass primitive types like integers (32 and 64bit only), floats and pointers and don't pass any structs without a pointer indirection the abi incompatibility shouldn't hit you.

view this post on Zulip bjorn3 (Aug 17 2023 at 08:53):

By the way maybe you could compile your C++ code using emscripten exporting a javascript interface and then call the exported javascript interface using wasm-bindgen from the rust code? https://emscripten.org/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html provides some documentation on how to export a javascript interface from emscripten. This is probably going to be slower than directly linking the C++ and rust code though.

view this post on Zulip bjorn3 (Aug 17 2023 at 08:56):

By the way for a URL parser is there a reason you aren't using the javascript URL parser or the url crate? There are two versions of the URL specification (the RFC1738 one and the WHATWG one) which are different in ways that can cause security issues. Browsers and the url crate use the WHATWG version. I don't know which variant your C++ URL parser uses.

view this post on Zulip Dominic Elm (Aug 17 2023 at 11:37):

Hm, I think what I'd like to pass is strings (as pointers maybe)

view this post on Zulip Dominic Elm (Aug 17 2023 at 11:40):

The problem I am running into is, even if I compile the lib to wasi, it somehow complains then about

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

view this post on Zulip Dominic Elm (Aug 17 2023 at 11:40):

Cause my lib type is crate-type = ["cdylib"]

view this post on Zulip Dominic Elm (Aug 17 2023 at 11:41):

But browser also don't closely follow WHATWG unfortunately, at least Chrome and FF

view this post on Zulip Dominic Elm (Aug 17 2023 at 11:41):

I wanna link https://www.ada-url.com/ because Node.js uses that parser and the browser's URL doesn't seem to be fully compliant with ada

WHATWG Compliant URL parser written with focus on compliance, performance and security across multiple platforms and languages.

view this post on Zulip Dominic Elm (Aug 17 2023 at 11:42):

Cause Chrome and FF are not fully spec compliant

view this post on Zulip bjorn3 (Aug 17 2023 at 14:03):

If you are doing URL parsing for security related purposes you did want to use the browser's URL parser rather than whatever the specification says precisely because the divergence can cause the browser to interpret URL's in ways you didn't expect.

Dominic Elm said:

Cause Chrome and FF are not fully spec compliant

This statement surprised me because the whole reason the WHATWG URL specification exists at all afaik is to codify the divergence between actual browsers and RFC1738, but it seems there are indeed some divergences between WHATWG and some actual browsers.

Dominic Elm said:

The problem I am running into is, even if I compile the lib to wasi, it somehow complains then about

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

Are you telling rustc where to find the library dir of the wasi-sdk using -L?

view this post on Zulip Dominic Elm (Aug 17 2023 at 14:27):

Do I have to pass the -L in the build.rs?

view this post on Zulip Dominic Elm (Aug 17 2023 at 14:28):

This is what my current build.rs looks like

fn main() {
    cc::Build::new()
        .cpp(true)
        .compiler("/opt/wasi-sdk/build/wasi-sdk-20.10g7c0558ba4159/bin/clang++")
        .flag("--sysroot=/opt/wasi-sdk/build/wasi-sdk-20.10g7c0558ba4159/share/wasi-sysroot")
        .include("./ada/include")
        .include("./ada/include/ada")
        .target("wasm32-wasi")
        .file("./ada/src/ada.cpp")
        .compile("ada");
}

view this post on Zulip Dominic Elm (Aug 17 2023 at 14:28):

But that results in the error that I posted earlier

view this post on Zulip bjorn3 (Aug 17 2023 at 14:44):

Try adding println!("cargo:rustc-link-search=/opt/wasi-sdk/build/wasi-sdk-20.10g7c0558ba4159/share/wasi-sysroot/lib"); (I think /opt/wasi-sdk/build/wasi-sdk-20.10g7c0558ba4159/share/wasi-sysroot/lib would be the directory containing libstdc++, but if not change it to the directory that does contain it)

view this post on Zulip Dominic Elm (Aug 17 2023 at 18:56):

Hm yea, doesn't seem to work

view this post on Zulip Dominic Elm (Aug 17 2023 at 18:57):

Tho that folder contains the following
image.png

view this post on Zulip Dominic Elm (Aug 17 2023 at 18:57):

So there is libc++.a

view this post on Zulip Dominic Elm (Aug 17 2023 at 18:58):

Oh wait

view this post on Zulip Dominic Elm (Aug 17 2023 at 18:58):

It's libc++

view this post on Zulip Dominic Elm (Aug 17 2023 at 18:58):

Not libstdc++

view this post on Zulip Dominic Elm (Aug 17 2023 at 18:58):

So maybe I can change it to use c++ as the standard lib

view this post on Zulip Dominic Elm (Aug 17 2023 at 18:59):

Uhhh that worked maybe :eyes:

view this post on Zulip Dominic Elm (Aug 17 2023 at 19:02):

Okay... I am a little closer

view this post on Zulip Dominic Elm (Aug 17 2023 at 19:02):

Now I am seeing a few imports, prolly from the stdlib

view this post on Zulip Dominic Elm (Aug 17 2023 at 19:02):

image.png

view this post on Zulip Dominic Elm (Aug 17 2023 at 19:02):

Any idea how I can get those or what I can do?

view this post on Zulip Dominic Elm (Aug 17 2023 at 19:12):

Ok passing -fno-exceptions will get rid of some

view this post on Zulip Dominic Elm (Aug 17 2023 at 19:26):

Down to these
image.png

view this post on Zulip Dominic Elm (Aug 17 2023 at 19:26):

Not sure what to do about those

view this post on Zulip bjorn3 (Aug 17 2023 at 19:31):

Abort and memchr are coming from libc normally with memchr being provided for you from the rust side. You could implement abort as a panic in rust. __cxa_atexit allows registering a function to run when exiting the current process. Probably fine to implement it as no-op. For the rest I'm not sure what they do. You could try implementing them as panic. If that doesn't work could you run their names through a C++ name demangler like c++filt? That may make their name more readable.

view this post on Zulip Dominic Elm (Aug 17 2023 at 19:41):

Run what through a demangler?

view this post on Zulip Dominic Elm (Aug 17 2023 at 19:48):

I am now linking libc++

view this post on Zulip Dominic Elm (Aug 17 2023 at 19:48):

Is there a way I can also include libc so that it may find memchr?

view this post on Zulip Dominic Elm (Aug 17 2023 at 19:52):

aha
image.png

view this post on Zulip Dominic Elm (Aug 17 2023 at 19:52):

Operators

view this post on Zulip Dominic Elm (Aug 17 2023 at 19:58):

Seems like libc++ is missing those?

view this post on Zulip Dominic Elm (Aug 17 2023 at 19:58):

Hm

view this post on Zulip Karel Hrkal (kajacx) (Aug 19 2023 at 14:34):

@Dominic Elm You can try using wasm-bridge, which is a create I built from loading and running wasm modules in Rust on the web. I have never tried it with C++, but that should not matter, as long as it's compiled to WASM correctly. The wasi support is still in progress though.

Provides a single unified API to run WASM modules on the desktop using wasmtime, or on the web using js-sys. - GitHub - kajacx/wasm-bridge: Provides a single unified API to run WASM modules on the ...

Last updated: Nov 22 2024 at 17:03 UTC