AR ホームベーカリー

オイラのアウトプット用ホームベーカリー!

AppleSillicon で古い Ruby を build する その3

せっかくなので、Rails 5.1 の古いプロジェクトで実際に Ruby 2.5 を動かせるか試してみた。

僕の場合の対応なので、個々のプロジェクトでは異なると思いますが、こんな古いバージョン使う以上自己責任だよ自己責任! という気持ちで参考情報として見てください。

これまでの流れ

donbulinux.hatenablog.jp

donbulinux.hatenablog.jp

対応が必要だったトコ

  • curb 0.9.4 を使っていてビルド失敗したので対応した
    • 0.9.11 にバージョンアップした
  • mysql2 がビルド失敗したので対応した
    • zstd のパスを雑に通した
    • ssl のパスを雑に通した

以下に詳細を書いておく。

curb 0.9.4 だったので 0.9.11 に bundle update curb した

元々 zipline 1.0.1 を使っていて、依存性の解決で以下のようになっていた。

    zipline (1.0.1)
      curb (>= 0.8.0, < 0.10)

zipline の対象バージョンからリリース時期や依存性解決に必要そうなトコから 2018 年あたりのものを選択して 0.9.x の最終版を選択したところシュッと解決できたのでオッケー。

Gemfile のバージョンアップ方法

https://qiita.com/morioka1206/items/19410fe414f441583998#gem%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E6%8C%87%E5%AE%9A%E6%96%B9%E6%B3%95

バージョン指定の記号をよく忘れるんだよなあ。

mysql2

ld: library 'zstd' not found

zstd のパスがなかったので、雑に通した https://zenn.dev/yukionodera/articles/how-to-fix-error-mysql2

export LIBRARY_PATH=$LIBRARY_PATH:$(brew --prefix zstd)/lib/

ld: library 'ssl' not found

mysql2 が参照したい OpenSSL のパスが通ってない? っぽいので、これ Ruby が依存する v1 系なのか MySQL が依存する v3 系なのか? とりあえずえいやって雑に通した。 https://qiita.com/ffggss/items/2a6e965c8c3133a92eb9#%E8%A3%9C%E8%B6%B3

❯ brew --prefix openssl
/opt/homebrew/opt/openssl@3
❯ bundle config --global build.mysql2 --with-opt-dir="$(brew --prefix openssl)"

動いたので大丈夫そう。

mysql2 公式の Readme

上記のどっちのパス問題だけど、Readme には以下のように書いてある

https://github.com/brianmario/mysql2?tab=readme-ov-file#mac-os-x

openssl@1.1 を使ったほうがよさそうだけど、

Later versions of MacOS no longer distribute a linkable OpenSSL library. It is common to use Homebrew or MacPorts to install OpenSSL. Make sure that both the Ruby runtime and MySQL client libraries are compiled with the same OpenSSL family, 1.0 or 1.1 or 3.0, since only one can be loaded at runtime.

MacOS の新しいバージョンでは、リンク可能な OpenSSL ライブラリは配布されなくなりました。 OpenSSL をインストールするには、Homebrew または MacPorts を使用するのが一般的です。実行時にロードできるのは 1 つだけであるため、Ruby ランタイムと MySQL クライアント ライブラリの両方が同じ OpenSSL ファミリ (1.0、1.1、または 3.0) でコンパイルされていることを確認してください。

とのことで、 RubyMySQL は同じ OpenSSL をリンクしてる前提の書き方なので、今回は Ruby 2.5 と MySQL 8.2 で動かすので当てはまらないので、動けば正義の理論でいく。

はい

はいじゃないが。

とはいえアレなので、追試として使っていた mysql2 0.5.3 を執筆時点で最新版の 0.5.6 にしてみた。

cat Gemfile

# 一応考慮はされていた
# gem 'mysql2', '>= 0.3.18', '~> 0.5'
# ちなみに Rails は Gemfile.lock を見たら rails (5.1.7) だったので普通にアレだけどまあ動く対象バージョンだった

❯ bundle update mysql2

... snip ...

Fetching mysql2 0.5.6 (was 0.5.3)
Installing mysql2 0.5.6 (was 0.5.3) with native extensions

... snip ...

Bundle updated!

一通り終わったので

動作確認を兼ねて最初から通します。

rm -rf vendor/bundle
❯ bundle install --path vendor/bundle

... snip ...

Bundle complete! 73 Gemfile dependencies, 191 gems now installed.

ということで無事最後まで bundle install が実行でき、中途半端にバージョンアップなどしていた環境が無事動きました。 やったあちょっと保守が楽になるぞ。

いつまでも古いバージョン使ってんじゃねえ

それは仰るとおりなのですが、往々にして予算の都合とか「エンドユーザに見えない部分より見える部分を優先しろ!」と滅茶苦茶怒られて、使っているライブラリ (UI や機能に影響するトコ) の差し替えで大規模に工数変わったり、機能や使い勝手が変更される、みたいなのが発生するので実施できていないんですよね。

という環境でした。

初期構築していた人が全員いなくなって、残ったのは spec が必ず落ちる (ダミーの初期データ投入タスクすらない) バージョンアップができない環境、となりめちゃくちゃ辛いのだけど、結局誰もやらないので巻き取るかあ〜、となったりしていたので最初の一歩としてマトモに動く環境を構築しなおせたのは良かった。

という訳で最後はちょっと愚痴っぽくなりましたが、古いプロジェクトの敗戦処理とかまきなおしをする (している) 人、がんばりましょう! 新年度なので一発景気づけという気持ちでした。