nokogiriのインストールでハマった件

自宅のMacVagrant弄っていて、プラグインをあれこれ試そうとインストールした際にちょっとハマったので、その時の問題解消までの経緯をメモしとく。

最初に結論を書いておくが、

keg-onlyのformulaのbrew linkを忘れるな!

という事です。以下蛇足。

Vagrantプラグインvagrant-omnibusのインストール時に以下のようなメッセージが出力された。

$ vagrant plugin install vagrant-omnibus
Installing the 'vagrant-omnibus' plugin. This can take a few minutes...
Building nokogiri using packaged libraries.
Building libxml2-2.8.0 for nokogiri with the following patches applied:
    - 0001-Fix-parser-local-buffers-size-problems.patch
    - 0002-Fix-entities-local-buffers-size-problems.patch
    - 0003-Fix-an-error-in-previous-commit.patch
    - 0004-Fix-potential-out-of-bound-access.patch
    - 0005-Detect-excessive-entities-expansion-upon-replacement.patch
    - 0006-Do-not-fetch-external-parsed-entities.patch
    - 0007-Enforce-XML_PARSER_EOF-state-handling-through-the-pa.patch
    - 0008-Improve-handling-of-xmlStopParser.patch
    - 0009-Fix-a-couple-of-return-without-value.patch
    - 0010-Keep-non-significant-blanks-node-in-HTML-parser.patch
    - 0011-Do-not-fetch-external-parameter-entities.patch
************************************************************************
IMPORTANT!  Nokogiri builds and uses a packaged version of libxml2.

If this is a concern for you and you want to use the system library
instead, abort this installation process and reinstall nokogiri as
follows:

    gem install nokogiri -- --use-system-libraries

If you are using Bundler, tell it to use the option:

    bundle config build.nokogiri --use-system-libraries
    bundle install

However, note that nokogiri does not necessarily support all versions
of libxml2.

For example, libxml2-2.9.0 and higher are currently known to be broken
and thus unsupported by nokogiri, due to compatibility problems and
XPath optimization bugs.
************************************************************************

メッセージの2行目から分かる通り、VagrantプラグインのインストールにRubyGemsのnokogiriが必要で、テスト用の環境にはまだnokogiriをインストールしていなかった為、nokogiriをビルドし始めた模様。

で、そのnokogiriなんだけど、バージョン1.6から依存ライブラリであるlibxml2(とlibxslt)を同梱するようになっており、インストール時に毎度それらも合わせてビルドされる為、非常に時間がかかる様になった。

メッセージの3行目以降はそれに関連したもので、既にマシンにlibxml2がインストールされている場合は、gemやbundlerのコマンドにオプションを付与する事で、nokogiriに同梱されているものではなく、インストール済みのものを使ってビルドする事ができるよと書いてある(libxml2のバージョンを全てサポートしてる訳じゃないが)。

私のMacには既にhomebrewでlibxml2がインストールされていて、バージョンも問題無かったので一旦vagrant-omnibusのインストールを中断し、改めてgemでnokogiriをインストールしたところ、以下の様なエラーメッセージが出力されてビルドがこけた。

$ NOKOGIRI_USE_SYSTEM_LIBRARIES=1 gem install nokogiri --no-rdoc --no-ri
Building native extensions.  This could take a while...
Building nokogiri using system libraries.
ERROR:  Error installing nokogiri:
    ERROR: Failed to build gem native extension.

        /usr/local/var/RBENV_ROOT/versions/1.9.3-p547/bin/ruby extconf.rb
Building nokogiri using system libraries.
libxml2 version 2.6.21 or later is required!
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

Provided configuration options:
    --with-opt-dir
    --without-opt-dir
    --with-opt-include
    --without-opt-include=${opt-dir}/include
    --with-opt-lib
    --without-opt-lib=${opt-dir}/lib
    --with-make-prog
    --without-make-prog
    --srcdir=.
    --curdir
    --ruby=/usr/local/var/RBENV_ROOT/versions/1.9.3-p547/bin/ruby
    --help
    --clean
    --use-system-libraries=true
    --with-zlib-dir
    --without-zlib-dir
    --with-zlib-include
    --without-zlib-include=${zlib-dir}/include
    --with-zlib-lib
    --without-zlib-lib=${zlib-dir}/lib
    --with-xml2-dir
    --without-xml2-dir
    --with-xml2-include
    --without-xml2-include=${xml2-dir}/include
    --with-xml2-lib
    --without-xml2-lib=${xml2-dir}/lib
    --with-libxml-2.0-config
    --without-libxml-2.0-config
    --with-pkg-config
    --without-pkg-config
    --with-xslt-dir
    --without-xslt-dir
    --with-xslt-include
    --without-xslt-include=${xslt-dir}/include
    --with-xslt-lib
    --without-xslt-lib=${xslt-dir}/lib
    --with-libxslt-config
    --without-libxslt-config
    --with-exslt-dir
    --without-exslt-dir
    --with-exslt-include
    --without-exslt-include=${exslt-dir}/include
    --with-exslt-lib
    --without-exslt-lib=${exslt-dir}/lib
    --with-libexslt-config
    --without-libexslt-config


Gem files will remain installed in /usr/local/var/RBENV_ROOT/versions/1.9.3-p547/gemsets/global/gems/nokogiri-1.6.2.1 for inspection.
Results logged to /usr/local/var/RBENV_ROOT/versions/1.9.3-p547/gemsets/global/gems/nokogiri-1.6.2.1/ext/nokogiri/gem_make.out

最初に挙げたメッセージと見比べれば分かるが、2行目のメッセージ内容が、

Building nokogiri using packaged libraries.

から、

Building nokogiri using system libraries.

に変わっているので、インストール済みのlibxml2を使う様に指定はされているのだが、libxml2が無いよと言われてビルドできない。

インストール自体はされているのに一体何故だ?と、この時点で普通にlibxml2が有効になっているかどうかを確認すべきだったが、有効になっているものだと思い込んでしまっており、気が付くまでに小一時程無駄にした。

思考と試行の末に漸くシンボリックリンクを疑い始め、brew infoしたら案の定libxml2が有効になっていなかった事を確認。何度か環境を作り直しているマシンだったので、以前構築した際にkeg-onlyのformulaを一部brew linkし忘れていたようだorz

以下のコマンドを実行してから再度nokogiriをビルドしたら無事にインストールできた。

$ brew link --force libxml2

これでやっとVagrantプラグインもインストールできましたとさ。めでたしめでたし。

rbenvのrehashみたいに、この辺を自動的に補完してくれる様なコマンドオプションとかないかなーと思って調べてみたけど無さそうなので、取り敢えず最後にもう一度、

keg-onlyのformulaのbrew linkを忘れるな!

大事な事なので以下略。おわり。