Aqutras Members' Blog

株式会社アキュトラスのメンバーが、技術情報などを楽しく書いています。

bundle install で libv8 がインストール出来ない問題への対応法

こんにちは,taniyuです.
今回は,仮眠中に起きた不幸な出来事について話します.

今回問題が発生してしまった環境は以下の通りになります.

  • OS: OS X El Capitan (10.11.4)
  • rails: 4.2.5
  • ruby: 2.2.2p95

発生した問題

bundle install 時に libv8のインストールがこけてしまう

仮眠終了後PCを見てみると更新がかかっていて,bundle install を再度する必要がありました.
そこで,bundle install を行ったところ,以下の様なエラーが出て,bundle install できなくなりました.

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    /usr/local/opt/rbenv/versions/2.2.2/bin/ruby -r ./siteconf20160406-17343-1xpa2c8.rb extconf.rb
creating Makefile
Compiling v8 for x64
Using python 2.7.11
Using compiler: /usr/bin/c++ (clang version 7.3.0)
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: /Users/taniyuu/RailsApp/libv8text/vendor/bundle/ruby/2.2.0/gems/libv8-3.16.14.13/vendor/v8/out/x64.release/obj.target/preparser_lib/src/atomicops_internals_x86_gcc.o has no symbols
In file included from ../src/accessors.cc:28:
In file included from ../src/v8.h:60:
In file included from ../src/objects-inl.h:38:
In file included from ../src/elements.h:32:
../src/objects.h:5252:44: error: shifting a negative signed value is undefined [-Werror,-Wshift-negative-value]
  static const int kElementsKindMask = (-1 << kElementsKindShift) &
                                        ~~ ^
../src/objects.h:7386:36: error: shifting a negative signed value is undefined [-Werror,-Wshift-negative-value]
      (~kMaxCachedArrayIndexLength << kArrayIndexHashLengthShift) |
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
2 errors generated.
...
An error occurred while installing libv8 (3.16.14.13), and Bundler cannot continue.
Make sure that `gem install libv8 -v '3.16.14.13'` succeeds before bundling.

原因と対処法

原因

原因は,therubyracerlibv8 の相性になります.
相性の良いバージョンをインストールしないと上手く行きません.

対処法

macの場合は, therubyracer はなくても大丈夫みたいです.(詳しい説明は後で行います)
なので,Gemfile から一時的にコメントアウトするなり,
そもそも bundle install 時に,developmentではインストールしないようにするといいです.

macでtherubyracerが必要ない理由について

まず,execjsについて説明します.execjsがあることで,rubyスクリプトから,
javascriptが実行できるようになります.execjsでは,javascriptエンジンを利用しており,
このjavascriptエンジンの一つが,therubyracerになります.

javascriptエンジンには他にも,Node.js や JavaScriptCore 等があります.
JavaScriptCoreは,OS X に含まれているものであり,これがあるためmacでは,
therubyracerを導入しなくても良くなります.

ちなみに,javascriptエンジンを確認する方法として,コンソールを起動し
以下のコマンドを叩くと確認できます.

[1] pry(main)> ExecJS.runtime.name
=> "JavaScriptCore"

参考情報

今回,記事の作成は,以下のサイトを参考にさせていただきました.

  1. Railsでlibv8/therubyracerがMacOSX(Yosemite)でインストールできない問題対策
  2. JavaScriptエンジンをインストールする
  3. Rubyからjavascriptを実行するExecJS

参考サイト1の方では,下記のように書くと動作するというコメントが有りましたが,
私の環境で試したところ,今度は,therubyracer について,libv8のエラーと似たような
エラーが出てしまいました.要因については,突き止められませんでした.

bundle config build.libv8 --with-system-v8