GraalVMを試してみた (Ruby 失敗編)

[前回 (GraalVMを試してみた)](https://qiita.com/sonodar/items/dcfafdfba8af2db53b16) の続きです。
結論として、Rails5.2は動きませんでした。面倒くさいので途中でやめました。

## Railsを試してみる

`ruby`は同梱されていないが、1コマンドで`truffleruby`がインストールできる。

```bash
[root@centos-local ~]# gu -c install org.graalvm.ruby
Downloading: Component catalog
Processing component archive: Component org.graalvm.ruby
Downloading: Component org.graalvm.ruby
Installing new component: Truffle.Ruby (org.graalvm.ruby, version 1.0.0-rc1)
[root@centos-local ~]# ruby -v
truffleruby 1.0.0-rc1, like ruby 2.3.7 <native build with Graal> [x86_64-linux]
```

`bundler`インストール。

```bash
[root@centos-local ~]# gem install bundler
ERROR:  Loading command: install (RuntimeError)
	you may need to install the system OpenSSL library libssl - see doc/user/installing-libssl.md (libssl.so: 共有オブジェクトファイルを開けません: そのようなファイルやディレクトリはありません)
ERROR:  While executing gem ... (NoMethodError)
    undefined method `invoke_with_build_args' for nil:NilClass
```

`openssl`がないと怒られたので入れる。

```bash
yum install -y openssl-devel
```

再チャレンジしたら成功した。1gemインストールするだけなのに10分くらい時間がかかった。

```bash
[root@centos-local ~]# gem install bundler
Fetching: bundler-1.16.1.gem (100%)
Successfully installed bundler-1.16.1
Parsing documentation for bundler-1.16.1
Installing ri documentation for bundler-1.16.1
Done installing documentation for bundler after 247 seconds
1 gem installed
```

`rails`をインストールする。

```bash
[root@centos-local ~]# mkdir graaruby; cd graaruby
[root@centos-local graaruby]# gem i rails --no-ri --no-rdoc
Fetching: concurrent-ruby-1.0.5.gem (100%)
Successfully installed concurrent-ruby-1.0.5
Fetching: i18n-1.0.1.gem (100%)
Successfully installed i18n-1.0.1
Fetching: thread_safe-0.3.6.gem (100%)
Successfully installed thread_safe-0.3.6
Fetching: tzinfo-1.2.5.gem (100%)
Successfully installed tzinfo-1.2.5
Fetching: activesupport-5.2.0.gem (100%)
Successfully installed activesupport-5.2.0
Fetching: rack-2.0.4.gem (100%)
Successfully installed rack-2.0.4
Fetching: rack-test-1.0.0.gem (100%)
Successfully installed rack-test-1.0.0
Fetching: mini_portile2-2.3.0.gem (100%)
Successfully installed mini_portile2-2.3.0
Fetching: nokogiri-1.8.2.gem (100%)
Building native extensions.  This could take a while...
ERROR:  Error installing rails:
	ERROR: Failed to build gem native extension.

    current directory: /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/nokogiri-1.8.2/ext/nokogiri
/var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/bin/truffleruby -r ./siteconf20180419-15512-1xuv5v8.rb extconf.rb
/var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/rbconfig-for-mkmf.rb:23:in `block in <top (required)>': clang does not appear to be available - you may need to install LLVM - see doc/user/installing-llvm.md (RuntimeError)
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/rbconfig-for-mkmf.rb:19:in `each'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/rbconfig-for-mkmf.rb:19:in `<top (required)>'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/truffle/lazy-rubygems.rb:20:in `gem_original_require'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/truffle/lazy-rubygems.rb:20:in `require'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/mri/mkmf.rb:11:in `<top (required)>'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/truffle/lazy-rubygems.rb:20:in `gem_original_require'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/truffle/lazy-rubygems.rb:20:in `require'
	from extconf.rb:4:in `<main>'

extconf failed, exit code 1

Gem files will remain installed in /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/nokogiri-1.8.2 for inspection.
Results logged to /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/extensions/x86_64-linux/2.3.0/nokogiri-1.8.2/gem_make.out
```

案の定、`nokogiri`のビルドに失敗。LLVM,clangと、ビルドに必要そうな`libxml2`などをインストールして再チャレンジ。

```bash
[root@centos-local graaruby]# yum install -y clang llvm 
[root@centos-local graaruby]# yum install -y libxml2-devel readline-devel libffi-devel libxslt-devel libyaml-devel
[root@centos-local graaruby]# gem i rails --no-ri --no-rdoc
Building native extensions.  This could take a while...
ERROR:  Error installing rails:
	ERROR: Failed to build gem native extension.

    current directory: /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/nokogiri-1.8.2/ext/nokogiri
/var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/bin/truffleruby -r ./siteconf20180419-15679-1xuv5v8.rb extconf.rb
/var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/rbconfig-for-mkmf.rb:33:in `block in <top (required)>': unsupported clang version: 3.4.2 - see doc/user/installing-llvm.md (RuntimeError)
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/rbconfig-for-mkmf.rb:19:in `each'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/rbconfig-for-mkmf.rb:19:in `<top (required)>'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/truffle/lazy-rubygems.rb:20:in `gem_original_require'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/truffle/lazy-rubygems.rb:20:in `require'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/mri/mkmf.rb:11:in `<top (required)>'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/truffle/lazy-rubygems.rb:20:in `gem_original_require'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/truffle/lazy-rubygems.rb:20:in `require'
	from extconf.rb:4:in `<main>'

extconf failed, exit code 1

Gem files will remain installed in /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/nokogiri-1.8.2 for inspection.
Results logged to /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/extensions/x86_64-linux/2.3.0/nokogiri-1.8.2/gem_make.out
```

`unsupported clang version: 3.4.2`とある。しまった、バージョン確認し忘れた。
Githubの[Issue](https://github.com/oracle/truffleruby/issues/62)によると`Currently, the script accepts LLVM 3.8, 3.9, 4.0 and 5.0.`とある。

[StackOverFlowの投稿](https://stackoverflow.com/questions/44219158/how-to-install-clang-and-llvm-3-9-on-centos-7)を参考にclang3.9をインストールする。

```bash
# 念のため削除
yum remove -y clang llvm
```

```bash
[root@centos-local graaruby]# cat <<-'__EOT__' > /etc/yum.repos.d/alonid-llvm-3.9.0.repo
[alonid-llvm-3.9.0]
name=Copr repo for llvm-3.9.0 owned by alonid
baseurl=https://copr-be.cloud.fedoraproject.org/results/alonid/llvm-3.9.0/epel-7-$basearch/
type=rpm-md
skip_if_unavailable=True
gpgcheck=1
gpgkey=https://copr-be.cloud.fedoraproject.org/results/alonid/llvm-3.9.0/pubkey.gpg
repo_gpgcheck=0
enabled=1
enabled_metadata=1
__EOT__
[root@centos-local graaruby]# yum install -y clang-3.9.0-devel llvm-3.9.0-devel
...
完了しました!
```

再々チャレンジ。

```bash
[root@centos-local graaruby]# gem i rails --no-ri --no-rdoc
Building native extensions.  This could take a while...
ERROR:  Error installing rails:
	ERROR: Failed to build gem native extension.

    current directory: /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/nokogiri-1.8.2/ext/nokogiri
/var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/bin/truffleruby -r ./siteconf20180419-15860-1xuv5v8.rb extconf.rb
/var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/rbconfig-for-mkmf.rb:23:in `block in <top (required)>': clang does not appear to be available - you may need to install LLVM - see doc/user/installing-llvm.md (RuntimeError)
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/rbconfig-for-mkmf.rb:19:in `each'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/rbconfig-for-mkmf.rb:19:in `<top (required)>'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/truffle/lazy-rubygems.rb:20:in `gem_original_require'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/truffle/lazy-rubygems.rb:20:in `require'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/mri/mkmf.rb:11:in `<top (required)>'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/truffle/lazy-rubygems.rb:20:in `gem_original_require'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/truffle/lazy-rubygems.rb:20:in `require'
	from extconf.rb:4:in `<main>'

extconf failed, exit code 1

Gem files will remain installed in /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/nokogiri-1.8.2 for inspection.
Results logged to /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/extensions/x86_64-linux/2.3.0/nokogiri-1.8.2/gem_make.out
```

`/var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/rbconfig-for-mkmf.rb`を見ると、`clang`に`PATH`が通っていないようだ。
`/opt/llvm-3.9.0`にインストールされていやがった。再々々チャレンジ。

```bash
[root@centos-local graaruby]# PATH=/opt/llvm-3.9.0/bin:$PATH gem install nokogiri --no-ri --no-rdoc -- --use-system-libraries
Building native extensions with: '--use-system-libraries'
This could take a while...
Successfully installed nokogiri-1.8.2
1 gem installed
[root@centos-local graaruby]# PATH=/opt/llvm-3.9.0/bin:$PATH gem i rails --no-ri --no-rdoc -- --use-system-libraries
...
Fetching: rails-5.2.0.gem (100%)
Successfully installed rails-5.2.0
29 gems installed
```

できた！！感動！！！
> 教訓：新しいものを試す場合はFedoraかUbuntuを使いましょう

ようやく`rails new`です。とりあえずお試しなのでもろもろをskip。

```bash
PATH=/opt/llvm-3.9.0/bin:$PATH \
rails new . \
  --skip-action-mailer --skip-active-record --skip-active-storage --skip-action-cable \
  --skip-coffee --skip-turbolinks --skip-test --skip-system-test
```

インストールは成功。いざ！

```bash
[root@centos-local graaruby]# bundle exec rails s
/var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/truffle/cext.rb:221:in `execute_without_conversion': Error in C extension code (SulongRuntimeException): (RuntimeError)
Cannot convert LLVMTruffleObject(LLVMTypedForeignObject:0) to LLVMAddress (IllegalStateException)
	from msgpack_packer_ext_registry_init in packer_ext_registry.c:33:11 (LLVM IR Function msgpack_packer_ext_registry_init in /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/msgpack-1.2.4/lib/msgpack/msgpack.su@3cd8d21a2cb8c85aa1b0e9c9f9c917c5356daeea_out.bc in Block {id: 0 name: %1})
	from Factory_initialize in factory_class.c:72:5 (LLVM IR Function Factory_initialize in /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/msgpack-1.2.4/lib/msgpack/msgpack.su@3cd8d21a2cb8c85aa1b0e9c9f9c917c5356daeea_out.bc in Block {id: 2 name: %15})
	from java.lang.Throwable.<init>(Throwable.java:287)
Caused by:
Message not supported: TO_NATIVE (UnsupportedMessageException)
	from java.lang.Throwable.<init>(Throwable.java:265)
	from java.lang.Exception.<init>(Exception.java:66)
	from com.oracle.truffle.api.interop.InteropException.<init>(InteropException.java:36)
	from com.oracle.truffle.api.interop.UnsupportedMessageException.<init>(UnsupportedMessageException.java:41)
	from com.oracle.truffle.api.interop.UnsupportedMessageException.raise(UnsupportedMessageException.java:68)
	from org.truffleruby.interop.RubyMessageResolution$ForeignToNativeNode.access(RubyMessageResolution.java:192)
	from org.truffleruby.interop.RubyMessageResolutionForeign$ForeignToNativeSubNode.accessWithTarget(RubyMessageResolutionForeign.java:503)
	from org.truffleruby.interop.RubyMessageResolutionForeignFactory$ForeignToNativeSubNodeGen.executeAndSpecialize(RubyMessageResolutionForeignFactory.java:602)
	from org.truffleruby.interop.RubyMessageResolutionForeignFactory$ForeignToNativeSubNodeGen.executeWithTarget(RubyMessageResolutionForeignFactory.java:588)
	from org.truffleruby.interop.RubyMessageResolutionForeign$ForeignToNativeSubNode$TO_NATIVERootNode.execute(RubyMessageResolutionForeign.java:520)
Translated to internal error
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/truffle/cext.rb:221:in `execute_with_mutex'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/truffle/truffle/cext_ruby.rb:27:in `initialize'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/msgpack-1.2.4/lib/msgpack.rb:22:in `new'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/msgpack-1.2.4/lib/msgpack.rb:22:in `MessagePack'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/msgpack-1.2.4/lib/msgpack.rb:21:in `<top (required)>'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/bootsnap-1.3.0/lib/bootsnap/load_path_cache/store.rb:3:in `require'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/bootsnap-1.3.0/lib/bootsnap/load_path_cache/store.rb:3:in `block in <top (required)>'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/bootsnap-1.3.0/lib/bootsnap/explicit_require.rb:40:in `with_gems'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/bootsnap-1.3.0/lib/bootsnap/load_path_cache/store.rb:3:in `<top (required)>'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/bootsnap-1.3.0/lib/bootsnap/load_path_cache.rb:55:in `require_relative'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/bootsnap-1.3.0/lib/bootsnap/load_path_cache.rb:55:in `<top (required)>'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/bootsnap-1.3.0/lib/bootsnap.rb:3:in `require_relative'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/bootsnap-1.3.0/lib/bootsnap.rb:3:in `<top (required)>'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/bootsnap-1.3.0/lib/bootsnap/setup.rb:1:in `require_relative'
	from /var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/bootsnap-1.3.0/lib/bootsnap/setup.rb:1:in `<top (required)>'
	from /root/graaruby/config/boot.rb:4:in `require'
	from /root/graaruby/config/boot.rb:4:in `<top (required)>'
	from bin/rails:3:in `require_relative'
	from bin/rails:3:in `<main>'
```

Oops!
`msgpack`に依存している`bootsnap`を削除して再々々々チャレンジ。

```bash
rm -rf ./* ./.git*
PATH=/opt/llvm-3.9.0/bin:$PATH \
rails new . --skip-bootsnap \
  --skip-action-mailer --skip-active-record --skip-active-storage --skip-action-cable \
  --skip-coffee --skip-turbolinks --skip-test --skip-system-test
```

```
[root@centos-local graaruby]# bundle exec rails s
Possibly unsupported Ruby implementation
/var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/bundler-1.16.1/lib/bundler/runtime.rb:84:in `block (2 levels) in require': There was an error while trying to load the gem 'sass-rails'. (Bundler::GemRequireError)
Gem Load Error is: undefined method `reachable?' for Sass::Util
Backtrace for gem load error is:
/var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/sass-3.5.6/lib/sass/util.rb:1087:in `module_function'
/var/lib/graalvm-1.0.0-rc1/jre/languages/ruby/lib/ruby/gems/2.3.0/gems/sass-3.5.6/lib/sass/util.rb:1087:in `block in Util'
...
```

もういいや。