trifectatechfoundation / zlib-rs

A safer zlib
zlib License
145 stars 15 forks source link

Wasm code using zlib-rs fails to load in browser, using wasm-pack #253

Open billyc opened 4 days ago

billyc commented 4 days ago

Does this library support being run inside a browser?

I am using wasm-pack to build the 0.4.0 library .wasm file and javascript bindings. I have a simple test case: I created a test project with zero other dependencies in Cargo.toml beyond zlib-rs-sys, zlib-rs, and wasm-bindgen.

Build using wasm-pack build --target web and try to load in browser.

From Vite:

In the console:

One of the dependencies in zlib-rs is pulling in the "env" dependency which does not exist in the browser. I can successfully load other WASM modules, and I can load this one if I comment out the use of zlib-rs and libz-rs-sys. You can see the import in the very first line of the built pkg/streamer.js file.

It seems other projects have similar issues with "env":

My setup:

Is this a known issue? Am I doing something dumb? Is there anything else I can do to get his working in browser? Is wasm-pack the problem and should I builld some other way?

More than happy to provide the project code, help debug etc.

billyc commented 4 days ago

I created a stripped down example that just imports zlib-rs and sends some console.logs to the browser window. You can see that it's looking for "env". https://github.com/simwrapper/xml-parser

Using wasm-dis I can see that the dependencies pulling in env are:

~ wasm-dis matsim_event_streamer_bg.wasm | grep env
 (import "env" "malloc" (func $fimport$0 (param i32) (result i32)))
 (import "env" "calloc" (func $fimport$1 (param i32 i32) (result i32)))

so it's the c-allocator thing. This is now definitely beyond my capability to debug...

bjorn3 commented 4 days ago

Try enabling the rust-allocator feature to use the memory allocator of libstd. The c-allocator feature is for when you want to use zlib-rs from C code.

billyc commented 4 days ago

I did try that just a moment ago -- the import "env" is still there. But I will keep investigating.

bjorn3 commented 4 days ago

You may need --no-default-features too to disable the c-allocator feature.

billyc commented 4 days ago

ooooh I will try that!

billyc commented 3 days ago

That solved the problem! I needed to make two changes:

  1. Edit Cargo.toml to set the rust-allocator and default-features flags:

    [dependencies]
    libz-rs-sys = {version = "0.4.0"}
    zlib-rs = {version="0.4.0", default-features=false, features=["rust-allocator"] }
  2. Then run wasm-pack with --no-default-features:

Without both changes, the import "env" was still present and breaking things. But with them both, I can now load the wasm and the code is running!

Thanks so much for your hint and rapid response! This made my weekend 🚀

billyc commented 3 days ago

EDIT - after testing a few different combinations, it looks like having the [dependencies] lines exactly as above is sufficient. There is no need to also use --no-default-features on the wasm-pack build line.

I'm calling this done! Thx