From 5534eb93c63a5f199583224bbf284d42e11ea09d Mon Sep 17 00:00:00 2001 From: Konstantin Shabanov Date: Thu, 25 May 2023 19:33:39 +0600 Subject: [PATCH] Improve wasm32-wasi support [Starting from 3.41.0 SQLite has wasm32-wasi support out of the box.][0] - Set `-DSQLITE_THREADSAFE=0`. Fixes: ``` $ wasmtime target/wasm32-wasi/release/examples/persons.wasm Error: failed to run main module `target/wasm32-wasi/release/examples/persons.wasm` Caused by: 0: failed to instantiate "target/wasm32-wasi/release/examples/persons.wasm" 1: unknown import: `env::pthread_mutexattr_init` has not been defined ``` - Drop `-DSQLITE_OS_OTHER`. Fixes: ``` $ wasmtime target/wasm32-wasi/release/examples/persons.wasm Error: failed to run main module `target/wasm32-wasi/release/examples/persons.wasm` Caused by: 0: failed to instantiate "target/wasm32-wasi/release/examples/persons.wasm" 1: unknown import: `env::sqlite3_os_init` has not been defined ``` - [Add wasi specific build flags][1] - Add basic example - Also, add instructions how to run it against wasm32-wasi. Using of file databases is also working, though `--mapdir` arg should be provided to `wasmtime run`. [0]: https://wasmlabs.dev/articles/sqlite-wasi-support/ [1]: https://github.com/vmware-labs/webassembly-language-runtimes/blob/main/libs/sqlite/wasi-patches/wlr-build.sh#L11 --- examples/persons/README.md | 28 +++++++++++++++++++++++++ examples/persons/main.rs | 42 ++++++++++++++++++++++++++++++++++++++ libsqlite3-sys/build.rs | 11 +++++++--- 3 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 examples/persons/README.md create mode 100644 examples/persons/main.rs diff --git a/examples/persons/README.md b/examples/persons/README.md new file mode 100644 index 0000000..edea920 --- /dev/null +++ b/examples/persons/README.md @@ -0,0 +1,28 @@ +# Persons example + +## Run + +``` +$ cargo run --example persons +``` + +## Run (wasm32-wasi) + +### Requisites + +- [wasi-sdk](https://github.com/WebAssembly/wasi-sdk) +- [wasmtime](https://wasmtime.dev/) + +``` +# Set to wasi-sdk directory +$ export WASI_SDK_PATH=`` +$ export CC_wasm32_wasi="${WASI_SDK_PATH}/bin/clang --sysroot=${WASI_SDK_PATH}/share/wasi-sysroot" +# Build +$ cargo build --example persons --target wasm32-wasi --release --features bundled +# Run +$ wasmtime target/wasm32-wasi/release/examples/persons.wasm +Found persons: +ID: 1, Name: Steven +ID: 2, Name: John +ID: 3, Name: Alex +``` diff --git a/examples/persons/main.rs b/examples/persons/main.rs new file mode 100644 index 0000000..a1a94ae --- /dev/null +++ b/examples/persons/main.rs @@ -0,0 +1,42 @@ +extern crate rusqlite; +use rusqlite::{Connection, Result}; + +struct Person { + id: i32, + name: String, +} +fn main() -> Result<()> { + let conn = Connection::open_in_memory()?; + + conn.execute( + "CREATE TABLE IF NOT EXISTS persons ( + id INTEGER PRIMARY KEY, + name TEXT NOT NULL + )", + (), // empty list of parameters. + )?; + + conn.execute( + "INSERT INTO persons (name) VALUES (?1), (?2), (?3)", + ["Steven", "John", "Alex"].map(|n| n.to_string()), + )?; + + let mut stmt = conn.prepare("SELECT id, name FROM persons")?; + let rows = stmt.query_map([], |row| { + Ok(Person { + id: row.get(0)?, + name: row.get(1)?, + }) + })?; + + println!("Found persons:"); + + for person in rows { + match person { + Ok(p) => println!("ID: {}, Name: {}", p.id, p.name), + Err(e) => eprintln!("Error: {:?}", e), + } + } + + Ok(()) +} diff --git a/libsqlite3-sys/build.rs b/libsqlite3-sys/build.rs index 37cbb79..48af5da 100644 --- a/libsqlite3-sys/build.rs +++ b/libsqlite3-sys/build.rs @@ -239,11 +239,16 @@ mod build_bundled { if !win_target() { cfg.flag("-DHAVE_LOCALTIME_R"); } - // Target wasm32-wasi can't compile the default VFS if env::var("TARGET").map_or(false, |v| v == "wasm32-wasi") { - cfg.flag("-DSQLITE_OS_OTHER") + cfg.flag("-USQLITE_THREADSAFE") + .flag("-DSQLITE_THREADSAFE=0") // https://github.com/rust-lang/rust/issues/74393 - .flag("-DLONGDOUBLE_TYPE=double"); + .flag("-DLONGDOUBLE_TYPE=double") + .flag("-D_WASI_EMULATED_MMAN") + .flag("-D_WASI_EMULATED_GETPID") + .flag("-D_WASI_EMULATED_SIGNAL") + .flag("-D_WASI_EMULATED_PROCESS_CLOCKS"); + if cfg!(feature = "wasm32-wasi-vfs") { cfg.file("sqlite3/wasm32-wasi-vfs.c"); }