bytecodealliance / wasi-rs

Experimental WASI API bindings for Rust
Apache License 2.0
271 stars 48 forks source link

module does not export a function named `cabi_realloc` #87

Closed greyltc closed 6 months ago

greyltc commented 6 months ago

Hi, I'm trying to build the examples here for the wasm32-wasip2 target. The cli-command example works fine, but the http-proxy example fails while linking with module does not export a function named 'cabi_realloc', see below.

Should I expect cargo build --release --example http-proxy --target wasm32-wasip2 to work?

[user@box tmp]$ git clone https://github.com/bytecodealliance/wasi.git
Cloning into 'wasi'...
remote: Enumerating objects: 679, done.
remote: Counting objects: 100% (279/279), done.
remote: Compressing objects: 100% (122/122), done.
remote: Total 679 (delta 167), reused 226 (delta 139), pack-reused 400
Receiving objects: 100% (679/679), 403.22 KiB | 1.88 MiB/s, done.
Resolving deltas: 100% (277/277), done.
[user@box tmp]$ cd wasi/
[user@box wasi]$ CARGO_HOME=cargocache cargo build --release --example cli-command --target wasm32-wasip2
    Updating crates.io index
  Downloaded wit-bindgen-rt v0.23.0
  Downloaded bitflags v2.5.0
  Downloaded 2 crates (47.0 KB) in 0.39s
   Compiling wit-bindgen-rt v0.23.0
   Compiling bitflags v2.5.0
   Compiling wasi v0.13.0+wasi-0.2.0 (/tmp/wasi)
    Finished `release` profile [optimized] target(s) in 3.17s
[user@box wasi]$ wasmtime target/wasm32-wasip2/release/examples/cli_command.wasm 
Hello, WASI![user@box wasi]$ CARGO_HOME=cargocache cargo build --release --example http-proxy --target wasm32-wasip2
   Compiling wasi v0.13.0+wasi-0.2.0 (/tmp/wasi)
error: linking with `wasm-component-ld` failed: exit status: 1
  |
  = note: LC_ALL="C" PATH="/usr/lib64/rustlib/x86_64-unknown-linux-gnu/bin:/usr/lib64/rustlib/x86_64-unknown-linux-gnu/bin/self-contained:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/opt/rocm/bin:/opt/thinlinc/bin" VSLANG="1033" "wasm-component-ld" "-flavor" "wasm" "--rsp-quoting=posix" "--export" "wasi:http/incoming-handler@0.2.0#handle" "-z" "stack-size=1048576" "--stack-first" "--allow-undefined" "--no-demangle" "/tmp/wasi/target/wasm32-wasip2/release/examples/http_proxy-a425eb9e94bd484a.http_proxy.3b0757da2dc923d8-cgu.0.rcgu.o" "/tmp/wasi/target/wasm32-wasip2/release/examples/http_proxy-a425eb9e94bd484a.18grhl5o9fgcjr5d.rcgu.o" "-L" "/tmp/wasi/target/wasm32-wasip2/release/deps" "-L" "/tmp/wasi/target/release/deps" "-L" "/tmp/wasi/cargocache/registry/src/index.crates.io-6f17d22bba15001f/wit-bindgen-rt-0.23.0/src" "-L" "/usr/lib64/rustlib/wasm32-wasip2/lib" "/tmp/wasi/target/wasm32-wasip2/release/deps/libwasi-e839c33fab6d70a2.rlib" "/tmp/wasi/target/wasm32-wasip2/release/deps/libwit_bindgen_rt-25abd45c1112fb45.rlib" "/tmp/wasi/target/wasm32-wasip2/release/deps/libbitflags-0532528c0b7f10d6.rlib" "/usr/lib64/rustlib/wasm32-wasip2/lib/libstd-f405c0a7d7d0fd1d.rlib" "/usr/lib64/rustlib/wasm32-wasip2/lib/libpanic_abort-e75ad6669edc5fb6.rlib" "/usr/lib64/rustlib/wasm32-wasip2/lib/libwasi-796730c34055a22d.rlib" "/usr/lib64/rustlib/wasm32-wasip2/lib/librustc_demangle-a938a99ac6cd4035.rlib" "/usr/lib64/rustlib/wasm32-wasip2/lib/libstd_detect-833b0d7ab4b617de.rlib" "/usr/lib64/rustlib/wasm32-wasip2/lib/libhashbrown-e4e034f12760e71c.rlib" "/usr/lib64/rustlib/wasm32-wasip2/lib/librustc_std_workspace_alloc-050c6ecc02afca0e.rlib" "/usr/lib64/rustlib/wasm32-wasip2/lib/libminiz_oxide-69d2df61022e5404.rlib" "/usr/lib64/rustlib/wasm32-wasip2/lib/libadler-0e6b36716feb6fc7.rlib" "/usr/lib64/rustlib/wasm32-wasip2/lib/libunwind-8a32ef503944b03f.rlib" "/usr/lib64/rustlib/wasm32-wasip2/lib/libcfg_if-2911d934b8235556.rlib" "/usr/lib64/rustlib/wasm32-wasip2/lib/liblibc-185bdaabfff9e17a.rlib" "-l" "c" "/usr/lib64/rustlib/wasm32-wasip2/lib/liballoc-9cbe34ea85261d1b.rlib" "/usr/lib64/rustlib/wasm32-wasip2/lib/librustc_std_workspace_core-1161e14aada579f0.rlib" "/usr/lib64/rustlib/wasm32-wasip2/lib/libcore-eb4dbd4b51791325.rlib" "/usr/lib64/rustlib/wasm32-wasip2/lib/libcompiler_builtins-ec362bee3c68a315.rlib" "-l" "wit_bindgen_cabi_realloc" "-L" "/usr/lib64/rustlib/wasm32-wasip2/lib" "-L" "/usr/lib64/rustlib/wasm32-wasip2/lib/self-contained" "-o" "/tmp/wasi/target/wasm32-wasip2/release/examples/http_proxy-a425eb9e94bd484a.wasm" "--gc-sections" "--no-entry" "-O3"
  = note: error: failed to encode component

          Caused by:
              0: module does not export a function named `cabi_realloc`

error: could not compile `wasi` (example "http-proxy") due to 1 previous error
alexcrichton commented 6 months ago

Thanks for the report! Can you detail how you got a wasm32-wasip2 compiler? I was poking at that locally and had a surprisingly difficult time getting this to work, but for other reasons unrelated to the one that you encountered. This may indicate a configuration issue or an issue with the wasip2 toolchain to smooth over.

greyltc commented 6 months ago

Can you detail how you got a wasm32-wasip2 compiler?

@alexcrichton sure, I built the 1.78.0 rustc release package for Arch Linux like this: https://gitlab.archlinux.org/greyltc/rust/-/blob/add-wasm32-wasip2/PKGBUILD?ref_type=heads#L73-230

but basically, that just amounted to adding

[target.wasm32-wasip2]
sanitizers = false
profiler = false
wasi-root = "/usr/share/wasi-sysroot"

to config.toml and "wasm32-wasip2" to the [build] target array. Which is a small departure from how the official Arch rust package is made: https://gitlab.archlinux.org/greyltc/rust/-/compare/main...add-wasm32-wasip2?from_project_id=38540
Did I leave anything out there?

Seems I also had to use your special linker, wasm-component-ld, which I built/packaged like this: https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=wasm-component-ld

alexcrichton commented 6 months ago

Ah ok makes sense! The wit-bindgen crate currently assumes that https://github.com/rust-lang/rust/pull/122411 is part of Rust, which didn't make the 1.78 release. The 1.79 release of Rust will be the first to include that PR which should resolve most of this error.

Otherwise though one important thing to note is that wasi-libc objects are built differently for wasm32-wasip1 and wasm32-wasip2, so you'll eventually want a distinct wasi-root for each target.

greyltc commented 6 months ago

https://github.com/rust-lang/rust/pull/122411 seems to have sorted it, thanks! I built the rust package with that PR patched in like this: https://gitlab.archlinux.org/greyltc/rust/-/compare/main...add-wasm32-wasip2?from_project_id=38540

I also made a wasip2-libc package which gives me a wasi-root that has a wasm32-wasip2 target in it: https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=wasip2-libc

and the missing cabi_realloc compile problem is gone:

$ CARGO_HOME=cargocache cargo build --release --example http-proxy --target wasm32-wasip2
    Updating crates.io index
  Downloaded wit-bindgen-rt v0.23.0
  Downloaded bitflags v2.5.0
  Downloaded 2 crates (47.0 KB) in 2.37s
   Compiling wit-bindgen-rt v0.23.0
   Compiling bitflags v2.5.0
   Compiling wasi v0.13.0+wasi-0.2.0 (/tmp/t4/wasi)
    Finished `release` profile [optimized] target(s) in 4.44s

Though I can't seem to run it successfully like I did with the cli_command example:

$ wasmtime target/wasm32-wasip2/release/examples/http_proxy.wasm
Error: failed to run main module `target/wasm32-wasip2/release/examples/http_proxy.wasm`

Caused by:
    0: component imports instance `wasi:http/types@0.2.0`, but a matching implementation was not found in the linker
    1: instance export `fields` has the wrong type
    2: resource implementation is missing
pchickey commented 6 months ago

To fix that error, the cli invocation to run an wasi-http proxy world is wasmtime serve.

greyltc commented 6 months ago

Thanks for your help, I very much appreciate it.

$ wasmtime serve target/wasm32-wasip2/release/examples/http_proxy.wasm
Error: component imports instance `wasi:cli/environment@0.2.0`, but a matching implementation was not found in the linker

Caused by:
    0: instance export `get-environment` has the wrong type
    1: function implementation is missing

wasmtime serve shows another error.

alexcrichton commented 6 months ago

Ah for that you'll want to pass -Scli to the wasmtime serve command.

greyltc commented 6 months ago
$ wasmtime serve -Scli target/wasm32-wasip2/release/examples/http_proxy.wasm
Serving HTTP on http://0.0.0.0:8080/

Works! :champagne: Thanks again.