MacBookPro を macOS Monterey にしたあと、一応プログラミング環境も整えたのですが、wxWidgets 関連の整備が実はまだ終わっていませんでした。
Monterey にしたときに、Homebrew をアップグレードしました。インストール済みのツールが自動的にアップデートされないように export HOMEBREW_NO_AUTO_UPDATE=1
としておいたのですが、いつの間にか mingw-w64 のバージョンが上がっていました。wxWidgets のビルドには支障ないのですが、私がどうしても必要としている Ruby-2.0.0 のビルドができなくなりました。(そんな古いバージョンを使うな、というツッコミは却下。使う理由があるから使っているわけで……)
コンパイラのバージョンを下げないとダメだな、と思ったのは、下のエラーメッセージを見たためです。"internal compiler error" はコンパイラのバグなので、コンパイラを入れ替えるしかありません。
during RTL pass: dwarf2
transcode.c: In function 'rb_econv_alloc':
transcode.c:891:1: internal compiler error: in dwarf2out_frame_debug_expr, at dwarf2cfi.cc:2112
891 | }
| ^
Please submit a full bug report, with preprocessed source (by using -freport-bug).
-fno-omit-frame-pointer
オプションを削れば通る、という報告も見かけました(https://bugs.ruby-lang.org/issues/20486)。しかし、別のところでエラーが出ます。
win32/win32.c:2255:14: error: 'FILE' {aka 'struct _iobuf'} has no member named '_file'
2255 | stdin->_file = open_null(0);
./include/ruby/win32.h:421:16: error: redefinition of 'fseeko64'
421 | #define fseeko fseeko64
FILE
構造体の内部メンバにアクセスする、というのは行儀良いスタイルではないので、ソースコード側にも問題はあるのですが、このバージョンを使うと決めている以上、なんとか突破するしかありません。
以前使っていた GCC のバージョンを調べたところ、11.2.0 では正常にビルドできていました。このバージョンまで戻ります。参考にしたのはこちら:「Homebrewで古いバージョンのパッケージをインストールする 2023年版」(karakaram-blog 2023/11/29)。
(1) ローカルマシンに Tap 用の Git リポジトリを作成
Homebrew の "tap" というのは、公式以外のフォーミュラをインストールするためのリポジトリです。今回は、独自の tap を作成して、そこに古いバージョンのフォーミュラをコピーしてくる、という作戦でいきます。
$ brew tap-new nagata/homebrew-taps
$ brew tap
homebrew/cask
homebrew/core
nagata/taps
(2) 古いバージョンのフォーミュラを独自 tap に置く
古いバージョンは、https://github.com/Homebrew/homebrew-core/
で Formula/m/mingw-w64.rb
を探し、その history から見つけます。history を辿っていくと、途中で Formula/mingw-w64.rb
に切り替わります。
それをさらに追っていくと、2022/04/04 の 10.0.0 バージョンがあります。
このファイルの中身を見ると、GCC が 11.2.0 であることが確認できます。
これを brew extract
で取得しようと思ったのですが、うまくいきません。
$ brew extract mingw-w64 --version=10.0.0 nagata/taps
→ これだと 10.0.0_6 を選んでしまう。
$ brew extract mingw-w64 --force --git-revision=042c68b nagata/taps
→ これで revision 042c68b を取得できたはずだが……
取得できたはずなんですが、中身を見ると、なぜか GCC が 13.2.0 になっています。どうやら、Formula/m/mingw-w64.rb
の最も古いバージョンに置き換えられてしまっているようです。
仕方がないので、10.0.0 バージョンの mingw-w64.rb
を手動でダウンロードして /usr/local/homebrew/Library/Taps/nagata/homebrew-taps/Formula/
にコピーしました。
(3) ビルド・インストールする
$ brew install nagata/taps/mingw-w64
私は、Homebrew のインストール先を、標準の /usr/local
ではなく /usr/local/homebrew
にしています。このため、いちいちバイナリをビルドすることが必要で、たいへん時間がかかります。それでも1時間ぐらいで終わりました。
(4) バージョンを固定する
brew pin
で、バージョンを固定することができます。独自リポジトリなので「新バージョン」が現れることはないはずですが、標準リポジトリの mingw-w64 と同じ名前にしているので、念のため設定しておきます。
$ brew pin nagata/taps/mingw-w64
$ brew list --pinned
mingw-w64
これで Ruby-2.0.0 はビルドできるようになりました。そのうち、wxWidgets がこのバージョンの GCC でビルドできなくなる日が来るでしょうから、その時には Ruby のバージョンの方をなんとかしないといけません。その時までは、このスタイルで続けようと思います。