Description
A Rust crate with C dependency that uses long double
targeting wasm32-wasi
links incorrectly, while clang can compile such programs to WebAssembly.
I tried this code:
// main.rs
fn main() {
unsafe { print_long_double() };
}
extern "C" {
fn print_long_double();
}
// build.rs
cc::Build::new()
.file("src/foo.c")
.include("src")
.compile("foo");
// foo.c
void print_long_double() {
srand(0);
long double x = rand();
printf("x = %Lf\n", x);
}
export CC_wasm32_wasi=/opt/wasi-sdk/bin/clang
export CARGO_TARGET_WASM32_WASI_LINKER=/opt/wasi-sdk/bin/clang
export RUSTFLAGS='-C target-feature=-crt-static -C link-arg=-lc-printscan-long-double'
cargo build --target wasm32-wasi
wasmtime target/wasm32-wasi/debug/long-double.wasm
I expected to see this happen: the program should run and print a random number, just like when I compile with clang.
Instead, this happened:
Error: failed to run main module `target/wasm32-wasi/debug/long-double.wasm`
Caused by:
0: failed to instantiate "target/wasm32-wasi/debug/long-double.wasm"
1: unknown import: `env::__floatsitf` has not been defined
Simple repo to reproduce with Docker: https://github.com/TjeuKayim/wasi-long-double
Motivation
I tried to compile rusqlite to WASI following the instructions at https://doc.rust-lang.org/nightly/nightly-rustc/rustc_target/spec/wasm32_wasi/index.html. This was one of the issues I ran into. A work-around is to pass this flag -DLONGDOUBLE_TYPE=double
. The weird thing is that when I compile sqlite with clang and wasi-sdk, it compiles and runs correctly. Also, other projects manage to compile sqlite to WebAssembly, like https://wapm.io/package/sqlite#shell.