quickjs-rs icon indicating copy to clipboard operation
quickjs-rs copied to clipboard

Support wasm32-unknown-unknown Target

Open dsherret opened this issue 4 years ago • 7 comments

Thanks for this project!

Is there any way to compile this in a lib crate to target wasm32-unknown-unknown? (ex. cargo build --release --target=wasm32-unknown-unknown)

I'm suspecting no. I tried and got this error:

error: failed to run custom build command for `libquickjs-sys v0.6.0`

Caused by:
  process didn't exit successfully: `/mnt/v/dprint/crates/test-plugin/target/release/build/libquickjs-sys-7f85a6e12a75c9e1/build-script-build` (exit code: 1)
--- stdout
TARGET = Some("wasm32-unknown-unknown")
HOST = Some("x86_64-unknown-linux-gnu")
CC_wasm32-unknown-unknown = None
CC_wasm32_unknown_unknown = None
TARGET_CC = None
CC = None
CFLAGS_wasm32-unknown-unknown = None
CFLAGS_wasm32_unknown_unknown = None
TARGET_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
DEBUG = Some("false")
CC_wasm32-unknown-unknown = None
CC_wasm32_unknown_unknown = None
TARGET_CC = None
CC = None
CFLAGS_wasm32-unknown-unknown = None
CFLAGS_wasm32_unknown_unknown = None
TARGET_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
CC_wasm32-unknown-unknown = None
CC_wasm32_unknown_unknown = None
TARGET_CC = None
CC = None
CFLAGS_wasm32-unknown-unknown = None
CFLAGS_wasm32_unknown_unknown = None
TARGET_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
CC_wasm32-unknown-unknown = None
CC_wasm32_unknown_unknown = None
TARGET_CC = None
CC = None
CFLAGS_wasm32-unknown-unknown = None
CFLAGS_wasm32_unknown_unknown = None
TARGET_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
CC_wasm32-unknown-unknown = None
CC_wasm32_unknown_unknown = None
TARGET_CC = None
CC = None
CFLAGS_wasm32-unknown-unknown = None
CFLAGS_wasm32_unknown_unknown = None
TARGET_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
CC_wasm32-unknown-unknown = None
CC_wasm32_unknown_unknown = None
TARGET_CC = None
CC = None
CFLAGS_wasm32-unknown-unknown = None
CFLAGS_wasm32_unknown_unknown = None
TARGET_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
CC_wasm32-unknown-unknown = None
CC_wasm32_unknown_unknown = None
TARGET_CC = None
CC = None
CFLAGS_wasm32-unknown-unknown = None
CFLAGS_wasm32_unknown_unknown = None
TARGET_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
CC_wasm32-unknown-unknown = None
CC_wasm32_unknown_unknown = None
TARGET_CC = None
CC = None
CFLAGS_wasm32-unknown-unknown = None
CFLAGS_wasm32_unknown_unknown = None
TARGET_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
CC_wasm32-unknown-unknown = None
CC_wasm32_unknown_unknown = None
TARGET_CC = None
CC = None
CFLAGS_wasm32-unknown-unknown = None
CFLAGS_wasm32_unknown_unknown = None
TARGET_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
CC_wasm32-unknown-unknown = None
CC_wasm32_unknown_unknown = None
TARGET_CC = None
CC = None
CFLAGS_wasm32-unknown-unknown = None
CFLAGS_wasm32_unknown_unknown = None
TARGET_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
CC_wasm32-unknown-unknown = None
CC_wasm32_unknown_unknown = None
TARGET_CC = None
CC = None
CFLAGS_wasm32-unknown-unknown = None
CFLAGS_wasm32_unknown_unknown = None
TARGET_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
CC_wasm32-unknown-unknown = None
CC_wasm32_unknown_unknown = None
TARGET_CC = None
CC = None
CFLAGS_wasm32-unknown-unknown = None
CFLAGS_wasm32_unknown_unknown = None
TARGET_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
CC_wasm32-unknown-unknown = None
CC_wasm32_unknown_unknown = None
TARGET_CC = None
CC = None
CFLAGS_wasm32-unknown-unknown = None
CFLAGS_wasm32_unknown_unknown = None
TARGET_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
CC_wasm32-unknown-unknown = None
CC_wasm32_unknown_unknown = None
TARGET_CC = None
CC = None
CFLAGS_wasm32-unknown-unknown = None
CFLAGS_wasm32_unknown_unknown = None
TARGET_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
running: "clang" "-O2" "-ffunction-sections" "-fdata-sections" "-fPIC" "--target=wasm32-unknown-unknown" "-Wall" "-Wextra" "-D_GNU_SOURCE" "-DCONFIG_VERSION=\"2020-04-12\"" "-DCONFIG_BIGNUM" "-o" "/mnt/v/dprint/crates/test-plugin/target/wasm32-unknown-unknown/release/build/libquickjs-sys-62382c90b72b3b52/out/quickjs/cutils.o" "-c" "/mnt/v/dprint/crates/test-plugin/target/wasm32-unknown-unknown/release/build/libquickjs-sys-62382c90b72b3b52/out/quickjs/cutils.c"
cargo:warning=In file included from /mnt/v/dprint/crates/test-plugin/target/wasm32-unknown-unknown/release/build/libquickjs-sys-62382c90b72b3b52/out/quickjs/cutils.c:25:
cargo:warning=/usr/include/stdlib.h:25:10: fatal error: 'bits/libc-header-start.h' file not found
cargo:warning=#include <bits/libc-header-start.h>
cargo:warning=         ^~~~~~~~~~~~~~~~~~~~~~~~~~
cargo:warning=1 error generated.
exit code: 1

--- stderr
Compiling quickjs...


error occurred: Command "clang" "-O2" "-ffunction-sections" "-fdata-sections" "-fPIC" "--target=wasm32-unknown-unknown" "-Wall" "-Wextra" "-D_GNU_SOURCE" "-DCONFIG_VERSION=\"2020-04-12\"" "-DCONFIG_BIGNUM" "-o" "/mnt/v/dprint/crates/test-plugin/target/wasm32-unknown-unknown/release/build/libquickjs-sys-62382c90b72b3b52/out/quickjs/cutils.o" "-c" "/mnt/v/dprint/crates/test-plugin/target/wasm32-unknown-unknown/release/build/libquickjs-sys-62382c90b72b3b52/out/quickjs/cutils.c" with args "clang" did not execute successfully (status code exit code: 1).

dsherret avatar Jun 03 '20 21:06 dsherret

I was able to compile this only on Mac by doing:

quick-js = "=0.3.0"

Once it's bumped to 0.3.3 it no longer works and the following error occurs:

cargo:warning=/test/target/wasm32-unknown-unknown/release/build/libquickjs-sys-3ceefb9672fa932f/out/quickjs/cutils.c:25:10: fatal error: 'stdlib.h' file not found
cargo:warning=#include <stdlib.h>
cargo:warning=         ^~~~~~~~~~
cargo:warning=1 error generated.
exit code: 1

Not sure why it only works on Mac, but at least it's working now!


That said, it looks like it doesn't work exactly because the following functions then need to be provided as imports to the wasm instance.

21 link errors:
(1 of 21) Import not found, namespace: env, name: __JS_FreeValue
(2 of 21) Import not found, namespace: env, name: JS_ToCStringLen2
(3 of 21) Import not found, namespace: env, name: JS_FreeCString
(4 of 21) Import not found, namespace: env, name: JS_IsArray
(5 of 21) Import not found, namespace: env, name: JS_GetOwnPropertyNames
(6 of 21) Import not found, namespace: env, name: JS_GetPropertyInternal
(7 of 21) Import not found, namespace: env, name: JS_AtomToString
(8 of 21) Import not found, namespace: env, name: JS_GetPropertyStr
(9 of 21) Import not found, namespace: env, name: JS_GetPropertyUint32
(10 of 21) Import not found, namespace: env, name: JS_FreeAtom
(11 of 21) Import not found, namespace: env, name: js_free
(12 of 21) Import not found, namespace: env, name: JS_ToString
(13 of 21) Import not found, namespace: env, name: JS_FreeContext
(14 of 21) Import not found, namespace: env, name: JS_FreeRuntime
(15 of 21) Import not found, namespace: env, name: JS_NewRuntime
(16 of 21) Import not found, namespace: env, name: JS_NewContext
(17 of 21) Import not found, namespace: env, name: JS_GetGlobalObject
(18 of 21) Import not found, namespace: env, name: JS_GetException
(19 of 21) Import not found, namespace: env, name: JS_ExecutePendingJob
(20 of 21) Import not found, namespace: env, name: JS_Eval
(21 of 21) Import not found, namespace: env, name: JS_Call

I wonder what determines these to show up needing to be imports? Edit: Oh, ok... these are the quickjs bindings that get used in the rust code.

dsherret avatar Jun 19 '20 18:06 dsherret

obviously there always is a way, but it isn't easy to do in this case - wasm32-unknown-unknown c interop is in an extremely basic state at the moment - there's no libc and the abi doesn't perfectly match.

I did compile it successfully by doing some modifications to emscripten (which definitely can't be pushed to production) and linking a modified version of quickjs to the resulting modified emscripten-compiled libc, it's definitely not something that can be achieved by making modifications to this crate alone

chayleaf avatar Oct 17 '20 16:10 chayleaf

Thanks for your effort! <3

I want to build quickjs as a wasm based mini vm and having wasm32-unknown-unknown target support would be super handy.

I have more experience working with rust/wasm than emscripten :(, I was able to build https://github.com/justjake/quickjs-emscripten but would prefer to have a rust/wasm version.

twop avatar Dec 03 '20 19:12 twop

I'm looking into this again.

It will require quite a few patches to the codebase though, sadly.

theduke avatar Feb 04 '21 20:02 theduke

Good news!

I managed to transpile Quickjs to Rust with c2rust, and I have the code running fine after some relatively sparse refactoring.

I will need to patch out the libc dependency, but a WASM build is relatively easy to do now.

theduke avatar Feb 20 '21 22:02 theduke

Little progress update:

I've done quite extensive cleanup of the c2rust generated code. I probably introduced some bugs during reafactoring of the types, but the basics all seem to work on x86. The code builds fine on wasm, but setting up a Context currently fails with an error.

I will probably continue to rewrite it step by step to idiomatic Rust, which is a lot of work but probably worthwile and can be done incrementally.

That also means that the code will diverge significantly from QuickJS, and will live in a different repo with a new name.

If anyone wants to play with the code or, even better, help out with porting, a preliminary version is published here: https://github.com/theduke/slimjs

theduke avatar Feb 24 '21 11:02 theduke

Hi @theduke I've been trying out your crate for a bit while trying to pick up some rust skills - awesome work!

I've ran into the same issue as mr @dsherret describes above and had a look at the quickjs-fork in the link above. I noticed it's been about a year since the last commit - did you abandon it or did you found a way forward with this?

jakob-lilliemarck avatar Jan 26 '22 20:01 jakob-lilliemarck