2025年03月23日

Homebrew の mingw-w64 を古いバージョンに戻す

 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 に切り替わります。

20250323-1.jpg

 それをさらに追っていくと、2022/04/04 の 10.0.0 バージョンがあります。

20250323-2.jpg

 このファイルの中身を見ると、GCC が 11.2.0 であることが確認できます。

20250323-3.jpg

 これを 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 のバージョンの方をなんとかしないといけません。その時までは、このスタイルで続けようと思います。

Posted at 2025年03月23日 23:12:09
email.png