桐生あんずです

日常やプログラミングについて書いています。

homebrewでbinutilsを入れておくとarとranlibのパスが変わってRuby3.0.x系のインストール時にビルドエラーが起きる

桐生あんずです。

タイトルそのままの話なのだけれど、備忘録としてブログに書き留めておく。

先日、Ruby3系をインストールする機会があったので入れようとしたところ以下のようなビルドエラーを吐くようになっていた。 bigdecimal.c周りでエラーが起きている模様。

In file included from bigdecimal.c:13:
./bigdecimal.h:122:1: error: redefinition of 'rb_array_const_ptr'
rb_array_const_ptr(VALUE a)
^
../.././include/ruby/internal/core/rarray.h:184:1: note: previous definition is here
rb_array_const_ptr(VALUE a)
^
In file included from bigdecimal.c:13:
./bigdecimal.h:139:1: error: static declaration of 'rb_sym2str' follows non-static declaration
rb_sym2str(VALUE sym)
^
../.././include/ruby/internal/symbol.h:63:7: note: previous declaration is here
VALUE rb_sym2str(VALUE);
      ^
bigdecimal.c:108:1: error: static declaration of 'rb_rational_num' follows non-static declaration
rb_rational_num(VALUE rat)
^
../.././include/ruby/internal/intern/rational.h:39:7: note: previous declaration is here
VALUE rb_rational_num(VALUE rat);
      ^
bigdecimal.c:120:1: error: static declaration of 'rb_rational_den' follows non-static declaration
rb_rational_den(VALUE rat)
^
../.././include/ruby/internal/intern/rational.h:40:7: note: previous declaration is here
VALUE rb_rational_den(VALUE rat);
      ^
bigdecimal.c:132:1: error: static declaration of 'rb_complex_real' follows non-static declaration
rb_complex_real(VALUE cmp)
^
../.././include/ruby/internal/intern/complex.h:38:7: note: previous declaration is here
VALUE rb_complex_real(VALUE z);
      ^
bigdecimal.c:144:1: error: static declaration of 'rb_complex_imag' follows non-static declaration
rb_complex_imag(VALUE cmp)
^
../.././include/ruby/internal/intern/complex.h:39:7: note: previous declaration is here
VALUE rb_complex_imag(VALUE z);
      ^
linking shared-object -test-/wait_for_single_fd.bundle
compiling new.c
compiling coverage.c
linking shared-object continuation.bundle
linking shared-object -test-/time.bundle
compiling nofree.c
compiling date_core.c
installing default bigdecimal libraries
compiling dbm.c
compiling digest.c
linking shared-object cgi/escape.bundle
compiling normalize.c
compiling etc.c
compiling qsort.c
6 errors generated.
make[2]: *** [bigdecimal.o] Error 1
make[1]: *** [ext/bigdecimal/all] Error 2
make[1]: *** Waiting for unfinished jobs....

このエラーの内容をもとに調べていくと、以下のissueが出てきた。 github.com

まさに同様のエラー内容だったので https://github.com/rbenv/ruby-build/issues/1505#issuecomment-752274233 のアドバイスの通りにComand Line Toolsの再インストールをしたが、エラーは出たままだった。

$ sudo rm -rf /Library/Developer/CommandLineTools
$ xcode-select --install
$ sudo xcode-select -s /Library/Developer/CommandLineTools

これは困ったな〜となって、社内のRubyに詳しい方に聞いてみたところ「homebrewで入れたパッケージの中でビルドを邪魔しているやつがあるので関係しそうなやつを消していくしかなさそう」というアドバイスをいただいた。

そのアドバイスに従って明らかにRubyのビルドエラーに関わってなさそうなパッケージを除外した結果、 binutilsが怪しいのでは?という結論に至り、物は試しと思い消してみたところなんと普通に通った。

理由を調べていくと、どうやらmac OSに標準のarライブラリと ranlibライブラリがbinutilsの内製の方にパスが切り替わってしまうとのこと。 以下の記事で分かりやすく説明されている。

naoyat.hatenablog.jp

実際に入れ直して試してみたところ本当にパスが切り替わっていた。

//binutilsインストール前
% which ar
/usr/bin/ar
% which ranlib
/usr/bin/ranlib

//binutilsインストール後
% which ar
/usr/local/opt/binutils/bin/ar
% which ranlib
/usr/local/opt/binutils/bin/ranlib

今回はRubyのインストールでも起きたが、他のライブラリのビルドインストール時にも同じような事が起きる模様。

qiita.com

今回の一番の問題として、表示されるエラーを調べても殆どが一番最初に見たissueの記事が多く引っかかってしまい、原因がbinutilsが入っていることを辿るのがめちゃくちゃ難しいというのがあった。(binutils ruby エラーといったように調べると同じ道を辿った人の記事は出てくるが、原因がbinutilsだとわからないと調べられないという厳しい現状)

そのような困難な状況ではあったが、社内の人からいただいたアドバイスをもとに行動したことで解決することができたので本当に感謝したい。

ちなみに、なぜbinutilsを入れていたのかを思い出してみたところ、CTFでバイナリ解析用のコマンドを入れたかったためにインストールしたのだと思われる。ちゃんとCTF用の環境を作っておきましょうというオチなのかもしれない。