wasmerio / wasmer-pack

MIT License
49 stars 5 forks source link

Migrate ruby.wasm over to wit-pack #41

Open Michael-F-Bryan opened 1 year ago

Michael-F-Bryan commented 1 year ago

We want to update the ruby.wasm project so it can use bindings generated from their WAPM package instead of their manually building ruby.wasm and wrapping it.

This requires:

Building

You can start up their development environment by running the following command from the repository's root directory:

$ docker run --rm -it \
    --volume $(pwd):/src -w "/src" \
    ghcr.io/ruby/ruby.wasm-builder:wasm32-unknown-wasi \
    /bin/bash

(note: this means all files and folders created during the build process will be owned by root on your host machine, but we can't use the --user $(id -u) trick because it breaks npm later on)

Full build instructions are available here, but you can use that Docker environment to compile from source. On my computer, this takes 5-15 minutes.

$ rake npm:ruby-head-wasm-wasi
...
$ tree -L 4 rubies/head-wasm32-unknown-wasi-full-js-debug
rubies/head-wasm32-unknown-wasi-full-js-debug/
└── usr/
    └── local/
        ├── bin/
        ...
        │   ├── irb
        │   └── ruby
        ├── include/
        │   └── ruby-3.2.0+2/
        ├── lib/
        │   ├── libruby-static.a
        │   ├── pkgconfig/
        │   └── ruby/
        └── share/
            └── man/

10 directories, 14 files
$ tree packages/npm-packages/ruby-head-wasm-wasi/dist
packages/npm-packages/ruby-head-wasm-wasi/dist/
├── bindgen/
│   ├── intrinsics.js
│   ├── rb-abi-guest.d.ts
│   ├── rb-abi-guest.js
│   ├── rb-js-abi-host.d.ts
│   └── rb-js-abi-host.js
...
├── index.cjs.js
├── index.d.ts
├── index.esm.js
├── index.js
├── index.umd.js
...
├── ruby.debug+stdlib.wasm
├── ruby+stdlib.wasm
└── ruby.wasm

1 directory, 28 files

Hopefully you won't need to call scripts manually, but the code that actually compiles ruby.wasm (the library, not the executable) and copies it to the ruby-wasm-wasi package's dist/ directory is here, however it only gets invoked from ruby-head-wasm-wasi's build script :shrug:

Architecture

Their packaging system seems a bit convoluted because they've got a "template" JavaScript package under packages/npm-packages/ruby-wasm-wasi/ which contains the actual bindings and a "HEAD" package (ruby-head-wasm-wasi) which seems to just re-export code from the template.

The API being exported can be found in rb-abi-guest.wit, while the functionality imported by the host is defined in rb-js-abi-host.wit. They've also created a hand-written wrapper which manages the library instantiation and makes calling library functions slightly easier.

The executables that have already been uploaded to WAPM are under packages/wapm-packages/ and just provide access to the ruby and irb commands.

Michael-F-Bryan commented 1 year ago

This probably requires #43 because ruby.wasm imports rb-js-api-host.wit.