Skip to content

Instantly share code, notes, and snippets.

@kateinoigakukun
Last active September 11, 2023 21:25
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kateinoigakukun/5caf3b83b2732b1653e91b0e75ce3390 to your computer and use it in GitHub Desktop.
Save kateinoigakukun/5caf3b83b2732b1653e91b0e75ce3390 to your computer and use it in GitHub Desktop.

How to use Bundler and RubyGems on WebAssembly

# Download prebuilt ruby
curl -LO https://github.com/ruby/ruby.wasm/releases/download/2022-08-09-a/ruby-head-wasm32-unknown-wasi-full.tar.gz
tar xfz ruby-head-wasm32-unknown-wasi-full.tar.gz

# Install the same version of native ruby to avoid bundler version mismatch in "BUNDLED WITH" of Gemfile.lock
rbenv install 3.2.0-dev
rbenv local 3.2.0-dev

# Setup Gemfile
bundle init
bundle add syntax_tree

# Install gems in vendor/bundle to mount it on WASI
bundle config set --local path 'vendor/bundle'
bundle install

cat <<EOS > my_app.rb
# 'require "bundler/setup"' is not precisely equivalent to 'bundle exec ...', but enough to load installed gems
require "bundler/setup"
require "syntax_tree"

pp SyntaxTree.parse("1 + 1")
EOS

# Options:
# --mapdir /usr::./head-wasm32-unknown-wasi-full/usr    Map ruby directory
# --mapdir /root::./                                    Map user script directory
# --env BUNDLE_GEMFILE=/root/Gemfile                    Tell bundler where the Gemfile located because WASI has no PWD concept
wasmtime run \
  --mapdir /usr::./head-wasm32-unknown-wasi-full/usr \
  --mapdir /root::./ \
  --env BUNDLE_GEMFILE=/root/Gemfile \
  head-wasm32-unknown-wasi-full/usr/local/bin/ruby -- /root/my_app.rb
@jtippett
Copy link

jtippett commented Jun 8, 2023

I've been playing with this trying to get it working. I'll use the dir structure in the repo README, which has src/ instead of root/.

Here's what I run (breaking it into 2 parts - I am not sure how the above could ever work, it needs to be built first, then run, right?)

wasi-vfs pack ruby.wasm --mapdir /src::./src --mapdir /usr::./3_2-wasm32-unknown-wasi-full/usr  -o my-ruby-app.wasm

wasmtime run --env BUNDLE_GEMFILE=/src/Gemfile my-ruby-app.wasm -- src/my_app.rb

Running that I get:

james@black-lagoon wasm % wasmtime run --env BUNDLE_GEMFILE=/src/Gemfile my-ruby-app.wasm -- src/my_app.rb
panicked at 'not yet implemented', src/wasi_snapshot_preview1.rs:594:36
Error: failed to run main module `my-ruby-app.wasm`

Caused by:
    0: failed to invoke command default
    1: error while executing at wasm backtrace:
           0: 0xa007ef - <unknown>!<wasm function 11958>
         [snip a bunch of stack trace....]
          43: 0xa2ce37 - <unknown>!<wasm function 12179>
       note: using the `WASMTIME_BACKTRACE_DETAILS=1` environment variable may show more debugging information
    2: wasm trap: wasm `unreachable` instruction executed

Any ideas? Do I need to be using HEAD instead of ruby-3_2-wasm32-unknown-wasi-full.tar.gz ?

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