ruby/ruby.wasm

"js" gem fails to install on M1 Mac

lnit opened this issue · 4 comments

lnit commented

I tried to execute rbwasm pack command with Gemfile.
But, js gem fails to install on my environment.

Appendix: https://evilmartians.com/chronicles/first-steps-with-ruby-wasm-or-building-ruby-next-playground

Current behavior

% bundle init
% bundle add ruby_wasm
% bundle add js
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Installing js 2.6.0 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

**snip**

ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [js.bundle] Error 1
Full console logs
% bundle add js
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Installing js 2.6.0 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    current directory: /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/js-2.6.0/ext/js
/Users/{*my_username*}/.rbenv/versions/3.3.1/bin/ruby extconf.rb
This extension is only for WebAssembly. Creating a dummy Makefile.
creating Makefile

current directory: /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/js-2.6.0/ext/js
make DESTDIR\= sitearchdir\=./.gem.20240522-51646-jbz248 sitelibdir\=./.gem.20240522-51646-jbz248 clean

current directory: /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/js-2.6.0/ext/js
make DESTDIR\= sitearchdir\=./.gem.20240522-51646-jbz248 sitelibdir\=./.gem.20240522-51646-jbz248
compiling js-core.c
js-core.c:441:5: warning: 'JS_ENABLE_COMPONENT_MODEL' is not defined, evaluates to 0 [-Wundef]
#if JS_ENABLE_COMPONENT_MODEL
    ^
js-core.c:459:58: warning: implicit conversion loses integer precision: 'long' to 'int32_t' (aka 'int') [-Wshorten-64-to-32]
    return jsvalue_s_new(rb_js_abi_host_int_to_js_number(FIX2LONG(obj)));
                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~
/Users/{*my_username*}/.rbenv/versions/3.3.1/include/ruby-3.3.0/ruby/internal/arithmetic/long.h:46:22: note: expanded from macro 'FIX2LONG'
#define FIX2LONG     RB_FIX2LONG          /**< @old{RB_FIX2LONG} */
                     ^
/Users/{*my_username*}/.rbenv/versions/3.3.1/include/ruby-3.3.0/ruby/internal/arithmetic/long.h:53:22: note: expanded from macro 'RB_FIX2LONG'
#define RB_FIX2LONG  rb_fix2long          /**< @alias{rb_fix2long} */
                     ^
js-core.c:514:5: warning: 'JS_ENABLE_COMPONENT_MODEL' is not defined, evaluates to 0 [-Wundef]
#if JS_ENABLE_COMPONENT_MODEL
    ^
3 warnings generated.
compiling witapi-core.c
witapi-core.c:22:16: warning: unknown attribute 'import_module' ignored [-Wunknown-attributes]
__attribute__((import_module("asyncify"), import_name("start_unwind"))) void
               ^~~~~~~~~~~~~~~~~~~~~~~~~
witapi-core.c:22:43: warning: unknown attribute 'import_name' ignored [-Wunknown-attributes]
__attribute__((import_module("asyncify"), import_name("start_unwind"))) void
                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~
witapi-core.c:30:16: warning: unknown attribute 'import_module' ignored [-Wunknown-attributes]
__attribute__((import_module("asyncify"), import_name("stop_unwind"))) void
               ^~~~~~~~~~~~~~~~~~~~~~~~~
witapi-core.c:30:43: warning: unknown attribute 'import_name' ignored [-Wunknown-attributes]
__attribute__((import_module("asyncify"), import_name("stop_unwind"))) void
                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~
witapi-core.c:38:16: warning: unknown attribute 'import_module' ignored [-Wunknown-attributes]
__attribute__((import_module("asyncify"), import_name("start_rewind"))) void
               ^~~~~~~~~~~~~~~~~~~~~~~~~
witapi-core.c:38:43: warning: unknown attribute 'import_name' ignored [-Wunknown-attributes]
__attribute__((import_module("asyncify"), import_name("start_rewind"))) void
                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~
witapi-core.c:40:16: warning: unknown attribute 'import_module' ignored [-Wunknown-attributes]
__attribute__((import_module("asyncify"), import_name("stop_rewind"))) void
               ^~~~~~~~~~~~~~~~~~~~~~~~~
witapi-core.c:40:43: warning: unknown attribute 'import_name' ignored [-Wunknown-attributes]
__attribute__((import_module("asyncify"), import_name("stop_rewind"))) void
                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~
witapi-core.c:65:16: warning: unknown attribute 'import_module' ignored [-Wunknown-attributes]
__attribute__((import_module("rb-js-abi-host"),
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
witapi-core.c:66:16: warning: unknown attribute 'import_name' ignored [-Wunknown-attributes]
               import_name("rb_wasm_throw_prohibit_rewind_exception")))
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
witapi-core.c:215:20: warning: implicit conversion loses integer precision: 'size_t' (aka 'unsigned long') to 'int' [-Wshorten-64-to-32]
  int argc = args->len;
      ~~~~   ~~~~~~^~~
witapi-core.c:225:46: warning: implicit conversion loses integer precision: 'size_t' (aka 'unsigned long') to 'int' [-Wshorten-64-to-32]
  RB_WASM_LIB_RT(result = ruby_options(args->len, c_args))
                          ~~~~~~~~~~~~ ~~~~~~^~~
witapi-core.c:91:9: note: expanded from macro 'RB_WASM_LIB_RT'
        MAIN_ENTRY;                                                            \
        ^~~~~~~~~~
witapi-core.c:264:54: warning: implicit conversion loses integer precision: 'size_t' (aka 'unsigned long') to 'int' [-Wshorten-64-to-32]
  return rb_funcallv(ctx->recv, ctx->mid, ctx->args->len, c_argv);
         ~~~~~~~~~~~                      ~~~~~~~~~~~^~~
witapi-core.c:287:10: warning: implicit conversion loses integer precision: 'ID' (aka 'unsigned long') to 'rb_abi_guest_rb_id_t' (aka 'unsigned int') [-Wshorten-64-to-32]
  return rb_intern((const char *)name->ptr);
  ~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/{*my_username*}/.rbenv/versions/3.3.1/include/ruby-3.3.0/ruby/internal/symbol.h:325:20: note: expanded from macro 'rb_intern'
     __extension__ ({ \
                   ^~~~
witapi-core.c:287:10: warning: implicit conversion loses integer precision: 'ID' (aka 'unsigned long') to 'rb_abi_guest_rb_id_t' (aka 'unsigned int') [-Wshorten-64-to-32]
  return rb_intern((const char *)name->ptr);
  ~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/{*my_username*}/.rbenv/versions/3.3.1/include/ruby-3.3.0/ruby/internal/symbol.h:329:6: note: expanded from macro 'rb_intern'
     (rb_intern)(str))
     ^~~~~~~~~~~~~~~~
witapi-core.c:309:10: warning: cast to smaller integer type 'uint32_t' (aka 'unsigned int') from 'void *' [-Wvoid-pointer-to-int-cast]
  return (uint32_t)DATA_PTR(obj);
         ^~~~~~~~~~~~~~~~~~~~~~~
witapi-core.c:344:40: warning: unused function 'rb_abi_export_rb_value_to_js' [-Wunused-function]
static rb_abi_guest_own_rb_abi_value_t rb_abi_export_rb_value_to_js(void) {
                                       ^
17 warnings generated.
linking shared-object js.bundle
Undefined symbols for architecture arm64:
  "_asyncify_start_rewind", referenced from:
      _rb_abi_lend_object in witapi-core.o
      _rb_abi_guest_rb_abi_value_dtor in witapi-core.o
      _rb_abi_guest_ruby_init in witapi-core.o
      _rb_abi_guest_ruby_sysinit in witapi-core.o
      _rb_abi_guest_ruby_options in witapi-core.o
      _rb_abi_guest_ruby_script in witapi-core.o
      _rb_abi_guest_ruby_init_loadpath in witapi-core.o
      ...
  "_asyncify_stop_unwind", referenced from:
      _rb_abi_lend_object in witapi-core.o
      _rb_abi_guest_rb_abi_value_dtor in witapi-core.o
      _rb_abi_guest_ruby_init in witapi-core.o
      _rb_abi_guest_ruby_sysinit in witapi-core.o
      _rb_abi_guest_ruby_options in witapi-core.o
      _rb_abi_guest_ruby_script in witapi-core.o
      _rb_abi_guest_ruby_init_loadpath in witapi-core.o
      ...
  "_rb_abi_guest_rb_abi_value_get", referenced from:
      _rb_funcallv_thunk in witapi-core.o
      _rb_abi_guest_rb_funcallv_protect in witapi-core.o
      _rb_abi_guest_rstring_ptr in witapi-core.o
      _rb_abi_guest_rb_abi_value_data_ptr in witapi-core.o
  "_rb_abi_guest_rb_abi_value_new", referenced from:
      _rb_abi_guest_rb_eval_string_protect in witapi-core.o
      _rb_abi_guest_rb_funcallv_protect in witapi-core.o
      _rb_abi_guest_rb_errinfo in witapi-core.o
  "_rb_abi_guest_rb_iseq_new", referenced from:
      _rb_abi_guest_ruby_options in witapi-core.o
  "_rb_asyncify_unwind_buf", referenced from:
      _rb_abi_lend_object in witapi-core.o
      _rb_abi_guest_rb_abi_value_dtor in witapi-core.o
      _rb_abi_guest_ruby_init in witapi-core.o
      _rb_abi_guest_ruby_sysinit in witapi-core.o
      _rb_abi_guest_ruby_options in witapi-core.o
      _rb_abi_guest_ruby_script in witapi-core.o
      _rb_abi_guest_ruby_init_loadpath in witapi-core.o
      ...
  "_rb_js_abi_host_bool_to_js_bool", referenced from:
      __rb_js_true_to_js in js-core.o
      __rb_js_false_to_js in js-core.o
  "_rb_js_abi_host_eval_js", referenced from:
      __rb_js_eval_js in js-core.o
  "_rb_js_abi_host_export_js_value_to_host", referenced from:
      __rb_js_export_to_js in js-core.o
  "_rb_js_abi_host_float_to_js_number", referenced from:
      __rb_js_float_to_js in js-core.o
  "_rb_js_abi_host_global_this", referenced from:
      __rb_js_global_this in js-core.o
  "_rb_js_abi_host_import_js_value_from_host", referenced from:
      __rb_js_import_from_js in js-core.o
  "_rb_js_abi_host_instance_of", referenced from:
      __rb_js_is_kind_of in js-core.o
  "_rb_js_abi_host_int_to_js_number", referenced from:
      __rb_js_integer_to_js in js-core.o
  "_rb_js_abi_host_is_js", referenced from:
      __rb_js_try_convert in js-core.o
      __rb_js_is_kind_of in js-core.o
      __rb_js_obj_aset in js-core.o
      __rb_js_obj_eql in js-core.o
      __rb_js_obj_call in js-core.o
  "_rb_js_abi_host_js_abi_value_free", referenced from:
      __rb_js_obj_aset in js-core.o
      _jsvalue_free in js-core.o
  "_rb_js_abi_host_js_value_equal", referenced from:
      __rb_js_obj_eql in js-core.o
  "_rb_js_abi_host_js_value_strictly_equal", referenced from:
      __rb_js_obj_strictly_eql in js-core.o
  "_rb_js_abi_host_js_value_to_integer", referenced from:
      __rb_js_obj_to_i in js-core.o
      __rb_js_obj_to_f in js-core.o
  "_rb_js_abi_host_js_value_to_string", referenced from:
      __rb_js_obj_to_s in js-core.o
  "_rb_js_abi_host_js_value_typeof", referenced from:
      __rb_js_obj_typeof in js-core.o
  "_rb_js_abi_host_proc_to_js_function", referenced from:
      __rb_js_proc_to_js in js-core.o
  "_rb_js_abi_host_raw_integer_free", referenced from:
      __rb_js_obj_to_i in js-core.o
      __rb_js_obj_to_f in js-core.o
  "_rb_js_abi_host_rb_object_to_js_rb_value", referenced from:
      __rb_js_obj_wrap in js-core.o
  "_rb_js_abi_host_reflect_apply", referenced from:
      __rb_js_obj_call in js-core.o
  "_rb_js_abi_host_reflect_get", referenced from:
      __rb_js_obj_aref in js-core.o
  "_rb_js_abi_host_reflect_set", referenced from:
      __rb_js_obj_aset in js-core.o
  "_rb_js_abi_host_string_to_js_string", referenced from:
      __rb_js_string_to_js in js-core.o
  "_rb_vm_bugreport", referenced from:
      _rb_abi_guest_rb_vm_bugreport in witapi-core.o
     (maybe you meant: _rb_abi_guest_rb_vm_bugreport)
  "_rb_wasm_handle_fiber_unwind", referenced from:
      _rb_abi_lend_object in witapi-core.o
      _rb_abi_guest_rb_abi_value_dtor in witapi-core.o
      _rb_abi_guest_ruby_init in witapi-core.o
      _rb_abi_guest_ruby_sysinit in witapi-core.o
      _rb_abi_guest_ruby_options in witapi-core.o
      _rb_abi_guest_ruby_script in witapi-core.o
      _rb_abi_guest_ruby_init_loadpath in witapi-core.o
      ...
  "_rb_wasm_handle_jmp_unwind", referenced from:
      _rb_abi_lend_object in witapi-core.o
      _rb_abi_guest_rb_abi_value_dtor in witapi-core.o
      _rb_abi_guest_ruby_init in witapi-core.o
      _rb_abi_guest_ruby_sysinit in witapi-core.o
      _rb_abi_guest_ruby_options in witapi-core.o
      _rb_abi_guest_ruby_script in witapi-core.o
      _rb_abi_guest_ruby_init_loadpath in witapi-core.o
      ...
  "_rb_wasm_handle_scan_unwind", referenced from:
      _rb_abi_lend_object in witapi-core.o
      _rb_abi_guest_rb_abi_value_dtor in witapi-core.o
      _rb_abi_guest_ruby_init in witapi-core.o
      _rb_abi_guest_ruby_sysinit in witapi-core.o
      _rb_abi_guest_ruby_options in witapi-core.o
      _rb_abi_guest_ruby_script in witapi-core.o
      _rb_abi_guest_ruby_init_loadpath in witapi-core.o
      ...
  "_rb_wasm_throw_prohibit_rewind_exception", referenced from:
      _rb_abi_lend_object in witapi-core.o
      _rb_abi_guest_rb_abi_value_dtor in witapi-core.o
      _rb_abi_guest_ruby_init in witapi-core.o
      _rb_abi_guest_ruby_sysinit in witapi-core.o
      _rb_abi_guest_ruby_options in witapi-core.o
      _rb_abi_guest_ruby_script in witapi-core.o
      _rb_abi_guest_ruby_init_loadpath in witapi-core.o
      ...
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [js.bundle] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/js-2.6.0 for inspection.
Results logged to /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/extensions/arm64-darwin-22/3.3.0/js-2.6.0/gem_make.out

  /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/3.3.0/rubygems/ext/builder.rb:125:in `run'
  /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/3.3.0/rubygems/ext/builder.rb:51:in `block in make'
  /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/3.3.0/rubygems/ext/builder.rb:43:in `each'
  /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/3.3.0/rubygems/ext/builder.rb:43:in `make'
  /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/3.3.0/rubygems/ext/ext_conf_builder.rb:42:in `build'
  /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/3.3.0/rubygems/ext/builder.rb:193:in `build_extension'
  /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/3.3.0/rubygems/ext/builder.rb:227:in `block in build_extensions'
  /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/3.3.0/rubygems/ext/builder.rb:224:in `each'
  /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/3.3.0/rubygems/ext/builder.rb:224:in `build_extensions'
  /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/3.3.0/rubygems/installer.rb:852:in `build_extensions'
  /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/3.3.0/bundler/rubygems_gem_installer.rb:76:in `build_extensions'
  /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/3.3.0/bundler/rubygems_gem_installer.rb:28:in `install'
  /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/3.3.0/bundler/source/rubygems.rb:205:in `install'
  /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/3.3.0/bundler/installer/gem_installer.rb:54:in `install'
  /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/3.3.0/bundler/installer/gem_installer.rb:16:in `install_from_spec'
  /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/3.3.0/bundler/installer/parallel_installer.rb:132:in `do_install'
  /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/3.3.0/bundler/installer/parallel_installer.rb:123:in `block in worker_pool'
  /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/3.3.0/bundler/worker.rb:62:in `apply_func'
  /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/3.3.0/bundler/worker.rb:57:in `block in process_queue'
  <internal:kernel>:187:in `loop'
  /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/3.3.0/bundler/worker.rb:54:in `process_queue'
  /Users/{*my_username*}/.rbenv/versions/3.3.1/lib/ruby/3.3.0/bundler/worker.rb:90:in `block (2 levels) in create_threads'

An error occurred while installing js (2.6.0), and Bundler cannot continue.

In Gemfile:
  js

Without the "js" gem, rbwasm pack command was successful.
Appendix: #358

% bundle init
% bundle add ruby_wasm
% bundle add rainbow
% bundle exec rbwasm build -o ruby.wasm
INFO: Using Gemfile: [#<Pathname:/{*path_to_project*}/Gemfile>]

*snip*

==> RubyWasm::CrossRubyProduct(ruby-3.3-wasm32-unknown-wasip1-full) -- done in 74.21s
  ==> tar -C /var/folders/rg/qcr634qs6s30ss3dz0r53g3r0000gp/T/d20240522-28914-zl6dd3/usr -xzf /{*path_to_project*}/rubies/ruby-3.3-wasm32-unknown-wasip1-full.tar.gz --strip-components\=2
INFO: Packaging gem: rainbow-3.1.1
INFO: Packaging setup.rb: bundle/setup.rb
INFO: Size: 51.37 MB

Environment

  • Ruby: ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin22]
    • Bundler: Bundler version 2.5.9
  • Rust: rustc 1.78.0 (9b00956e5 2024-04-29)
  • Device:
    • OS: MacOS Ventura
    • Chip: Apple M1 Mac

It might be an error with my setup. Am I missing something?

OK, I guess it happens with Xcode 14.0...14.3 due to -Wl,-undefined,dynamic_lookup issue. Anyway, compiling C source files on non-wasm platform is unnecessary and we should not. I'll push a patch to fix this.

I hope f3e6c73 fixed the issue. I'm making a new release of js gem.

I pushed js gem 2.6.1 including the fix. Could you try it again?

lnit commented

@kateinoigakukun Thanks for the fast response!

I installed js gem 2.6.1.
This issue was fixed! 👍

% bundle install
Fetching gem metadata from https://rubygems.org/..
Resolving dependencies...
Fetching js 2.6.1
Installing js 2.6.1 with native extensions
Bundle complete! 3 Gemfile dependencies, 4 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.

Thank you very much!!