readline 6.3環境においてパッチを適用し、Rubyをコンパイル

2014.04.19

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Rubyがビルドできない!?

現在、私が関わっている案件のフロントエンドの開発にて、
compassというCSSのフレームワークを用いています。

当該フレームワークを用いるためには、Rubyのインストールが必要なのですが、
2014/04/17現在Homebrewでrbenv + ruby-build環境にてRubyをインストールしようとするとエラーとなります。

これはHomebrewが導入するReadlineのバージョン(6.3)に対して、
Rubyのコンパイラが対応していないのが原因になります。
ruby-buildも当該現象は把握してはいるが、Ruby側が対応するべきだろうというスタンスの為、
今現在コンパイルするためには、パッチを手動で当てる必要があります。

前提条件環境

下記の記事をもとにhomebrewのインストールとrbenv ruby-buildのインストールはすんでいるものとします。

社内AWSエンジニア向けMac用ツールまとめ資料を公開してみる | Developers.IO

なお、rbenv ruby-buildはhomebrewからインストールが可能になっております。

$ brew install rbenv 
$ brew install ruby-build

readlineとopenssl、libyamlもbrewで入れたバージョンを参照することにします。
上記をbrewでインストールすることとします。

$ brew install openssl 
$ brew install readline 
$ brew install libyaml

まずは失敗することを確認

$  rbenv install 2.1.0
Downloading ruby-2.1.0.tar.gz...
-> http://dqw8nmjcqpjn7.cloudfront.net/9e6386d53f5200a3e7069107405b93f7
Installing ruby-2.1.0...

BUILD FAILED

Inspect or clean up the working tree at /var/folders/x2/x7hmbd_52pj1styzdqv7698r0000gn/T/ruby-build.20140418141335.20999
Results logged to /var/folders/x2/x7hmbd_52pj1styzdqv7698r0000gn/T/ruby-build.20140418141335.20999.log

Last 10 log lines:
compiling ossl_x509ext.c
compiling ossl_x509name.c
compiling ossl_x509req.c
compiling ossl_x509revoked.c
1 warning generated.
compiling ossl_x509store.c
installing default openssl libraries
linking shared-object openssl.bundle
linking shared-object ripper.bundle
make: *** [build-ext] Error 2

画面に表示されたエラーを参照するにOpenSSLが悪さをしているように見えますが、 ログファイルを参照すると、画面に表示されたエラーより前にreadline関連でエラーが起きていることがわかります

readline.c:1977:26: error: use of undeclared identifier 'Function'
    rl_pre_input_hook = (Function *)readline_pre_input_hook;
                         ^
readline.c:1977:36: error: expected expression
    rl_pre_input_hook = (Function *)readline_pre_input_hook;
                                   ^
2 errors generated.

パッチを適用しインストール

当該箇所に関して対応を行ったパッチを適用し、インストールを行うとします。

参考サイト Build failure on 2.x and solution (related to readline) · Issue #526 · sstephenson/ruby-build · GitHub

$ curl -fsSL https://gist.github.com/mislav/a18b9d7f0dc5b9efc162.txt | rbenv install --patch 2.1.0
Downloading ruby-2.1.0.tar.gz...
-> http://dqw8nmjcqpjn7.cloudfront.net/9e6386d53f5200a3e7069107405b93f7
Installing ruby-2.1.0...
patching file ext/readline/readline.c
patching file ext/readline/extconf.rb
patching file ext/readline/extconf.rb
Installed ruby-2.1.0 to /usr/local/opt/rbenv/versions/2.1.0

無事にインストールができました。
ついでにOpenSSLもHeartbleed対応版が導入されていることも確認します。

 $ rbenv local 2.1.0
$ ruby -v
ruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-darwin13.0]
$ ruby -ropenssl -e 'p OpenSSL::OPENSSL_VERSION'
OpenSSL 1.0.1g 7 Apr 2014"

まとめ

Heartbleed対策を行おうとOpenSSLを更新し、Rubyをコンパイルしようとしたところ当該現象に遭遇しました。
画面に出てくるエラーもOpenSSLっぽいのでそれが原因かと思い調べてもわからず、
ruby-buildのgithubをみたところ対応策が見つかったので解決に至りました。