rbenv installで失敗する問題を解消 on Arch Linux

以下の条件で失敗したので、対応過程を残す。

条件

* Arch Linux
* 2.0系、2.1系で失敗
* 1.9系は成功
* pacmanによるRuby 2.1のインストールには成功
* rbenvはanyenvで導入

# 結論

以下のコマンドを実行したら上手くいった。

```zsh
rbenv install --patch 2.1.1 < <(curl -sSL 'https://projects.archlinux.org/svntogit/packages.git/plain/ruby/trunk/0001-Fix-undeclared-identifier-error-by-using-the-actual-.patch?id=d54cc2645013754f6a303075eb22df1eecb7676a')
```

ここで`File to patch:`と聞かれるので、`ext/readline/readline.c`を入力する。

# 過程

誤った対応（後述）をして記事を公開したところ、コメント欄にてありがたいご指摘を頂き、現在の形に至った。

Rubyのコードにpatchを当てる必要があるとのことだった。
対象のpatchはこちら。
https://projects.archlinux.org/svntogit/packages.git/tree/ruby/trunk/0001-Fix-undeclared-identifier-error-by-using-the-actual-.patch?id=d54cc2645013754f6a303075eb22df1eecb7676a

plainのリンクで生のpatchファイルが取得できる。

次に、rbenvでpatchを当ててインストールする方法を調査した。

ruby-buildのREADMEにpatchの当て方が書いてある
https://github.com/sstephenson/ruby-build
「Applying patches to Ruby before compiling」のセクションを参照。


# 以前の誤った対応記録

履歴を見れば分かるには分かるのだが、どんな勘違いをしていたか明確に残しておく。

## 結論（偽物）

以下のコマンドで上手く行ったと勘違い。
とりあえずインストールはできて動作もするが、readlineが使えない。

```zsh
RUBY_CONFIGURE_OPTS=--with-readline-dir="/usr/lib/libreadline.so" rbenv install 2.1.1
```

ruby-build、readlineという組み合わせでググると、readlineマターで失敗しするというのはArch Linuxに限らずちょいちょい見かける。

## 過程（迷走の記録）

まずは純朴にインストールしようとした。

```zsh
$ rbenv install 2.1.1
```

すると以下のエラーが出て失敗した。

```text
Inspect or clean up the working tree at /tmp/ruby-build.20140303235140.25701
Results logged to /tmp/ruby-build.20140303235140.25701.log

Last 10 log lines:
linking shared-object openssl.so
make[2]: Leaving directory '/tmp/ruby-build.20140303235140.25701/ruby-2.1.1/ext/openssl'
linking shared-object dl/callback.so
make[2]: Leaving directory '/tmp/ruby-build.20140303235140.25701/ruby-2.1.1/ext/dl/callback'
linking shared-object ripper.so
make[2]: Leaving directory '/tmp/ruby-build.20140303235140.25701/ruby-2.1.1/ext/ripper'
make[1]: Leaving directory '/tmp/ruby-build.20140303235140.25701/ruby-2.1.1'
uncommon.mk:180: recipe for target 'build-ext' failed
make: *** [build-ext] Error 2
```

ここで、エラーメッセージでググってみた。他にも同じ問題に悩んだ人もいるだろう。

まずは

```text
uncommon.mk:180: recipe for target 'build-ext' failed
```

で調べてみたが、こちらはまともな情報がヒットせず。

そこで広げて「build-ext error」でググってみたところ、`openssl`、`readline`をオプションで指定すれば良いという話をよく見かけた。
Mac OS Xでの話ばかり。Archの話は見かけない。

加えて、エラーメッセージに出ている大本のログファイルである、 /tmp/ruby-build.20140303235140.25701.log を確認してみた。

エラーメッセージでは`Error 2`とあったので、その上をたどると`Error 1`を発見した。

```text
readline.c: 関数 ‘Init_readline’ 内:
readline.c:1977:26: エラー: ‘Function’ が宣言されていません (この関数内での最初の使用)
     rl_pre_input_hook = (Function *)readline_pre_input_hook;
                          ^
readline.c:1977:26: 備考: 未宣言の識別子は出現した各関数内で一回のみ報告されます
readline.c:1977:36: エラー: expected expression before ‘)’ token
     rl_pre_input_hook = (Function *)readline_pre_input_hook;
                                    ^
readline.c: トップレベル:
readline.c:634:1: 警告: ‘readline_pre_input_hook’ が定義されましたが使用されません [-Wunused-function]
 readline_pre_input_hook(void)
 ^
make[2]: Leaving directory '/tmp/ruby-build.20140305230735.2209/ruby-2.1.1/ext/psych'
make[2]: Leaving directory '/tmp/ruby-build.20140305230735.2209/ruby-2.1.1/ext/rbconfig/sizeof'
Makefile:228: recipe for target 'readline.o' failed
make[2]: *** [readline.o] Error 1
```

`LANG`が`ja_JP.UTF-8`なので日本語だ。英語でかつ同じ問題で悩んでいる方、ぐぐラビリティが低くて恐縮。

つまるところ、opensslの前にreadlineの辺りでコケている。

というわけで、まずはオプションでreadlineのパスを指定してみることにした。

パスの調べ方だが、`find`してもいいが、`pacman`を使えばパッケージの関連ファイルのパスが分かる。

```zsh
$ pacman -Ql readline
```

アタリがつけば`find`でもいいが、そうでなければこちらの方が時間が短いかと思う。

ここから`.so`ファイルの場所を特定し、`RUBY_CONFIGURE_OPTS`で指定してみたら上手くいった。

以上をもって、無事に解決。

と思ったら、そんなことは全くなかった。