Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add documentation on how to build js.wasm #5

Open
cipriancraciun opened this issue Jan 16, 2025 · 5 comments
Open

Add documentation on how to build js.wasm #5

cipriancraciun opened this issue Jan 16, 2025 · 5 comments

Comments

@cipriancraciun
Copy link

I want to experiment with SpiderMonkey in a WASI environment, but via the CLI (i.e. running on my laptop on Linux).

I've managed to download a pre-built js.wasm as pointed by the data.json (like for example https://firefoxci.taskcluster-artifacts.net/CyxYoAnjT2eDPE02QnbGQA/0/public/build/js.wasm), and run that with wasmtime, and it works.

However, I want to be able to build my own js.wasm, and thus I've tried to follow the SpiderMonkey build information and peeked into the taskcluster files in the source code, however I've failed to actually get the code to build. (At the moment I'm blocked on how to instruct clang where the WASI-SDK lives.)

Could you please write a short section in the readme on how to build the js.wasm?

@jandem
Copy link
Contributor

jandem commented Jan 16, 2025

Are you able to build a non-WASI SpiderMonkey JS shell?

For a WASI build I have a mozconfig file with the following contents:

ac_add_options --enable-application=js
ac_add_options --target=wasm32-unknown-wasi

ac_add_options --enable-bootstrap
ac_add_options --disable-stdcxx-compat
ac_add_options --disable-clang-plugin
ac_add_options --without-system-zlib
ac_add_options --without-intl-api
ac_add_options --without-temporal-api
ac_add_options --disable-jit
ac_add_options --disable-shared-js
ac_add_options --disable-shared-memory
ac_add_options --disable-tests
ac_add_options --disable-jemalloc

ac_add_options --disable-debug-symbols

ac_add_options --disable-debug
ac_add_options --enable-optimize

I can then do this:

$ export MOZCONFIG=/my/mozconfig/file
$ ./mach build
...
$ wasmtime obj-wasm32-unknown-wasi/dist/bin/js
js>

The configure flags used for our WASI CI build you can find here.

@cipriancraciun
Copy link
Author

Are you able to build a non-WASI SpiderMonkey JS shell?

Yes, that works withouth any issues.

For a WASI build I have a mozconfig file with the following contents: [...]

I have something similar to what you've given (I'll have to experiment with your options).

I can then do this:

./mach build

And unfortunately here lies the major issue:

  • what does one need to have installed in order to actually build it? (in addition to what is needed for the native build;)
  • for example I managed to get a WASM build going after downloading from https://github.com/WebAssembly/wasi-sdk the wasi-sdk-25.0-x86_64-linux and wasi-sysroot-25.0 bundles;
  • however, I can't just put on the PATH the bin from the wasi-sdk as the build fails saying it doesn't know about the host target;
  • I had to manually specify CC, CXX, and AR in the mozconfig, plus --sysroot;
  • however, this still didn't work I also had to copy into /usr/lib64/clang/17/lib/{wasi,wasip1,wasip2} the respective libclang_rt.builtins-wasm32.a file from the wasi-sdk bundle;
  • and that still wasn't enough, as clang was complaining about missing crt.o; then I tried to play with zig cc as compiler (which didn't work), but by just installing zig, the build went through; (I can't imagine why clang found some files that are part of the zig package...)

Thus, the major pain-point in building the WASM version is finding the right build tool combination, and it would be nice if you could document what are the expected tools (including the current versions you are using).


For reference, for those using OpenSUSE Leap 15.6, I got the build running by having the following:

  • Rust 1.84.0, via rust-up, but I think any Rust since 1.76 works (I've tried it in another experiment;)
  • rust-cbindgen (from package, but from cargo install should probably work also);
  • clang17, and llvm17;
  • zig -- as noted, for some reason it's a required ingredient somehow; (at least in brings in some file that otherwise Clang fails to find;)
  • (for context, I also have binutils, gcc, make, and other build essentials installed;)

I've been trying to build SpiderMonkey from Firefox 128.6 ESR release.

And here is the config I've been using that finally worked for me:

cat >| ./release--wasi.conf << EOS

ac_add_options --enable-project=js
ac_add_options --enable-application=js

ac_add_options --enable-js-shell
ac_add_options --disable-shared-js
ac_add_options --disable-export-js

ac_add_options --enable-release
ac_add_options --enable-optimize
ac_add_options --disable-debug
ac_add_options --disable-debug-symbols
ac_add_options --enable-optimize=-O3

ac_add_options --disable-jit
ac_add_options --enable-portable-baseline-interp
ac_add_options --enable-portable-baseline-interp-force

ac_add_options --disable-wasm-jspi
ac_add_options --wasm-no-experimental
ac_add_options --disable-ctypes
ac_add_options --disable-simulator
ac_add_options --disable-tests
ac_add_options --disable-shared-memory
ac_add_options --without-system-zlib
ac_add_options --without-system-icu
ac_add_options --without-intl-api

ac_add_options --target=wasm32-wasip1
ac_add_options --host=x86_64-unknown-linux-gnu

mk_add_options CC=$( exec -- readlink -e -- ./wasi-sdk-25.0-x86_64-linux/bin/clang )
mk_add_options CXX=$( exec -- readlink -e -- ./wasi-sdk-25.0-x86_64-linux/bin/clang++ )
mk_add_options AR=$( exec -- readlink -e -- ./wasi-sdk-25.0-x86_64-linux/bin/ar )
mk_add_options LD=$( exec -- readlink -e -- ./wasi-sdk-25.0-x86_64-linux/bin/lld )
ac_add_options --with-sysroot=$( exec -- readlink -e -- ./wasi-sysroot-25.0 )

mk_add_options MOZ_OBJDIR=${TMPDIR:-}/mozjs--build/build/wasi
mk_add_options AUTOCLOBBER=1

EOS

Which then is built with (mind the env -i which clears the environment, and starts a pristine one):

rm -R -f -- "${TMPDIR:-}/mozjs--build/build/wasi"

nice -n 19 -- \
env -i \
        PATH="$( exec -- readlink -e -- "${HOME}/.rustup/toolchains/1.84.0-x86_64-unknown-linux-gnu/bin" ):/usr/bin" \
        CARGO_HOME="$( exec -- readlink -e -- "${HOME}/.rustup/toolchains/1.84.0-x86_64-unknown-linux-gnu" )" \
        HOME="${TMPDIR:-/tmp}/mozjs--build/home" \
        TMPDIR="${TMPDIR:-/tmp}/mozjs--build/tmp" \
        MOZCONFIG="$( exec -- readlink -e -- ./release--wasi.conf )" \
./mach \
            --no-interactive \
        build \
            --jobs 64 \
#

Then collect the output:

cp -T -- "${TMPDIR:-}/mozjs--build/build/wasi/dist/bin/js" ./js.wasm

@jandem
Copy link
Contributor

jandem commented Jan 17, 2025

Hm I expected ./mach bootstrap to install the WASI toolchain for this. You may have to select you're building "Firefox" instead of "SpiderMonkey" there; no idea.

@cipriancraciun
Copy link
Author

Hm I expected ./mach bootstrap to install [...]

I didn't choose to run bootstrap because I am running OpenSUSE Leap 15.6, and I would prefer to install packages by hand (I assume that the bootstrap option would run things with sudo). However, I did try to install the documented dependencies.

I'll try to look into the bootstrap scripts to see what I am missing.

@turbolent
Copy link

turbolent commented Jan 24, 2025

Is there any way to compile without the reference-types and multivalue feature?

From wasm-objdump:

Custom:
 - name: "target_features"
  - [+] bulk-memory
  - [+] multivalue
  - [+] mutable-globals
  - [+] reference-types
  - [+] sign-ext

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants