ruby/ruby.wasm

Can't use Emscripten release and can't manually build

Closed this issue · 2 comments

I made a simple project in CMake, Emscripten, and C++, with just a single main.cpp. It compiles, builds, and runs fine in the browser.

Try with Pre-Built

To add Ruby, I first tried downloading ruby-3.4-wasm32-unknown-emscripten-full.tar.gz from here:

In my main file, I added some Ruby test code:

#include <emscripten.h>
#include <emscripten/html5.h>
#include <ruby.h>

void run_ems_frame() {}

int main(int /*argc*/,char** /*argv*/) {
  ruby_init();
  rb_eval_string("puts 'hi from Ruby'");
  ruby_finalize();

  emscripten_set_main_loop(run_ems_frame,0,false);

  return 0;
}

And updated my CMakeLists.txt:

target_link_libraries("${BIN_NAME}" PRIVATE
    "ruby-3.4-wasm32-unknown-emscripten-full/usr/local/lib/libruby-static.a"
)
target_include_directories("${BIN_NAME}"
    SYSTEM PUBLIC "ruby-3.4-wasm32-unknown-emscripten-full/usr/local/include/ruby-3.4.0"
                  "ruby-3.4-wasm32-unknown-emscripten-full/usr/local/include/ruby-3.4.0/wasm32-emscripten"
)

It compiles fine, but always fails on building/linking:

error: undefined symbol: saveSetjmp (referenced by root reference (e.g. compiled C/C++ code))
warning: To disable errors for undefined symbols use `-sERROR_ON_UNDEFINED_SYMBOLS=0`
warning: _saveSetjmp may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: testSetjmp (referenced by root reference (e.g. compiled C/C++ code))
warning: _testSetjmp may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
Error: Aborting compilation due to previous errors
em++: error:

I tried adding _saveSetjmp/saveSetjmp to EXPORTED_FUNCTIONS, but still fails.

I also tried pre-release build 2025-03-05-a and same errors.

After researching online, it seems like people got similar errors with pre-built Emscripten libraries and the recommendation was to build yourself, so I decided to try that...

Trying to Build Ruby

I cloned tag 2.7.1, but after building failed, I also tried with main and tag 2025-03-05-a.

Steps, I tried to build using CONTRIBUTING.md:

git clone https://github.com/ruby/ruby.wasm.git --recursive --recurse-submodules
cd ruby.wasm/
./bin/setup

That all succeeds.

Now when I try to run rake build:head-wasm32-unknown-emscripten-full or even bundle exec rake compile, I always get the same error:

errors
NoMethodError: undefined method `empty?' for nil (NoMethodError)

      if !stderr.empty?
                ^^^^^^^
~/.gem/ruby/3.3.4/gems/rb_sys-0.9.108/lib/rb_sys/error.rb:35:in `initialize'
~/.gem/ruby/3.3.4/gems/rb_sys-0.9.108/lib/rb_sys/cargo/metadata.rb:154:in `new'
~/.gem/ruby/3.3.4/gems/rb_sys-0.9.108/lib/rb_sys/cargo/metadata.rb:154:in `rescue in cargo_metadata'
~/.gem/ruby/3.3.4/gems/rb_sys-0.9.108/lib/rb_sys/cargo/metadata.rb:141:in `cargo_metadata'
~/.gem/ruby/3.3.4/gems/rb_sys-0.9.108/lib/rb_sys/cargo/metadata.rb:127:in `load!'
~/.gem/ruby/3.3.4/gems/rb_sys-0.9.108/lib/rb_sys/cargo/metadata.rb:26:in `new_or_inferred'
~/.gem/ruby/3.3.4/gems/rb_sys-0.9.108/lib/rb_sys/extensiontask.rb:60:in `cargo_metadata'
~/.gem/ruby/3.3.4/gems/rb_sys-0.9.108/lib/rb_sys/extensiontask.rb:33:in `init'
~/.gem/ruby/3.3.4/gems/rake-compiler-1.2.9/lib/rake/baseextensiontask.rb:29:in `initialize'
~/.gem/ruby/3.3.4/gems/rb_sys-0.9.108/lib/rb_sys/extensiontask.rb:26:in `initialize'
~/Code/projects/rasby/ruby.wasm/rakelib/gem.rake:14:in `new'
~/Code/projects/rasby/ruby.wasm/rakelib/gem.rake:14:in `<top (required)>'
~/.gem/ruby/3.3.4/gems/rake-13.2.1/exe/rake:27:in `<top (required)>'

Caused by:
Errno::ENOENT: No such file or directory - cargo (Errno::ENOENT)
~/.gem/ruby/3.3.4/gems/rb_sys-0.9.108/lib/rb_sys/cargo/metadata.rb:148:in `cargo_metadata'
~/.gem/ruby/3.3.4/gems/rb_sys-0.9.108/lib/rb_sys/cargo/metadata.rb:127:in `load!'
~/.gem/ruby/3.3.4/gems/rb_sys-0.9.108/lib/rb_sys/cargo/metadata.rb:26:in `new_or_inferred'
~/.gem/ruby/3.3.4/gems/rb_sys-0.9.108/lib/rb_sys/extensiontask.rb:60:in `cargo_metadata'
~/.gem/ruby/3.3.4/gems/rb_sys-0.9.108/lib/rb_sys/extensiontask.rb:33:in `init'
~/.gem/ruby/3.3.4/gems/rake-compiler-1.2.9/lib/rake/baseextensiontask.rb:29:in `initialize'
~/.gem/ruby/3.3.4/gems/rb_sys-0.9.108/lib/rb_sys/extensiontask.rb:26:in `initialize'
~/Code/projects/rasby/ruby.wasm/rakelib/gem.rake:14:in `new'
~/Code/projects/rasby/ruby.wasm/rakelib/gem.rake:14:in `<top (required)>'
~/.gem/ruby/3.3.4/gems/rake-13.2.1/exe/rake:27:in `<top (required)>'

I haven't tried linking libruby-static.a to a custom main driver script, but you need to make sure that:

Also did adding EXPORTED_FUNCTIONS change any error message?


For building ruby.wasm project locally, please make sure you have installed Rust toolchain first.

Thank you!

I downgraded Emscripten to 3.1.54 and now works. I wonder if that could be added to the filename of the download (ruby-3.4-wasm32-unknown-emscripten-3.1.54-full.tar.gz) or something else (like a file in top dir)? So can be found easily.

As for building ruby.wasm, I didn't know it needed Rust, so that makes sense. Should that be added to CONTRIBUTING.md? I see it mentions Rust, but only for .wit files.