とーますメモ

Ruby on Rails / Goなどの学習メモ

【Ruby】MacでRailsが突然動かなくなった話

2021年にまたやらかした。
thoames.hatenadiary.jp

=============

原因が何だったのか定かではないが、
恐らくXcode関係かbrew関係のコマンドを弄ったかが原因で
Railsを起動しようとしたところ以下のようなエラーが表示された。

$ bundle exec rails s

...
LoadError - library not found for class Digest::SHA1 -- digest/sha1
...

ruby on rails - LoadError: dlopen(digest/sha1.bundle): Symbol not found: _rb_Digest_SHA1_Finish - Stack Overflow
ios - Ruby: LoadError - library not found for class Digest::SHA1 -- digest/sha1 - Stack Overflow

どうやらOpenSSLが直接的な原因であったようで
/usr/local/opt/opensslのシンボリックリンクが「../Cellar/openssl@1.1/1.1.1d」を指していたのが原因っぽい。(あくまでも予想)

そしてこの問題が発生したときは、情報があまりなかったので
安易にRubyを再インストールすればよいと思ってしまい、使用していたRuby 2.3.1を消してしまったことから悲劇が始まった。

Rbenvで古いバージョン(2.3.1)がインストールできない

Ruby環境の構築にはrbenv及びbundlerを使用している。
そしてRubyを再インストールするために、以下のコマンドで2.3.1が以下のようなビルドエラーになるという状態になった

$ rbenv install 2.3.1

...
The Ruby openssl extension was not compiled.
ERROR: Ruby install aborted due to missing extensions
...

調べてみると自分の環境が、opensslのバージョンが1.1系になっており
2.4より古いRubyは、openssl@1.1がインストールされた環境ではビルドが失敗するとのこと。
なので古いopenssl経由でビルドする必要があるみたい。

自分の場合は/usr/local/opt/opensslのシンボリックリンクが、openssl@1.1を向いていたので
これを古いバージョン(以前使用していたのは1.0.2q)へ向け直す必要があったので、brew switchと組み合わせて以下のようなコマンドで、なんとか2.3.1がインストールできた。

ちなみに古いバージョンのopensslは「/usr/local/Cellar/openssl」に入っている。

$ brew switch openssl 1.0.2q
$ RUBY_CONFIGURE_OPTS="--with-openssl-dir=/usr/local/opt/openssl" rbenv install 2.3.1
$ rbenv rehash
$ rbenv global 2.3.1
$ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin18]

[参考]
Mac環境でopenssl@1.1があると古いRubyのインストールに失敗する - Qiita
Cannot install Ruby versions < 2.4 because of openssl@1.1 dependency · Issue #1353 · rbenv/ruby-build · GitHub
[Ruby] rbenv で「The Ruby openssl extension was not compiled.」が発生したときの対処 - Qiita

Bundlerが原因でRailsが動かない。

bundle exec rails sを行うために、bundlerのインストールが必要だが、後々2系だと自分が使用しているgemと相性が悪いので
古いバージョンのbundlerをインストールした

$ gem install bundler -v 1.17.1
$ gem list

...
bundler (1.17.1)
...

Nokogiri(1.6.6.2)がインストールできない

どうやらmacOS SDK headerなるものが関係あるらしいので、以下の記事を参考にmacOS_SDK_headersをインストールしようとしたが
バージョンが古い?とのことでインストールされなかった。
mojaveでbundle installできない - Qiita

$ sudo open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg

どうやら最新のものがAppleのサイト(https://developer.apple.com/download/more/)からダウンロードできるらしい。
サイトに接続し、デベロッパーアカウントを作り、最新のpkgをダウンロードすることに成功し、無事にmacOK_SDK_headersのインストールに成功。
【macOS Mojave】macOS MojaveにアプデしたらCのヘッダーファイルが読み込まれなくなった件 - 空飛ぶセロ弾き

その後、以下のコマンドを叩いて、nokogiriをインストールすることに成功した。

$ bundle config build.nokogiri --use-system-libraries=true --with-xml2-include="$(xcrun --show-sdk-path)"/usr/include/libxml2
$ bundle install

[参考]
https://www.it-swarm.net/ja/ruby/mac-os-sierra-1012%E3%81%ABnokogiri%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/827764805/
ruby on rails - An error occurred while installing nokogiri (1.6.6.2), and Bundler cannot continue - Stack Overflow

lib8とtherubyracerがインストールできない

以下の記事と同じことを行ったらインストールできた。

$ brew install v8-315
$ bundle config --local build.libv8 --with-system-v8
You are replacing the current local value of build.libv8, which is currently nil
$ bundle config --local build.therubyracer --with-v8-dir=$(brew --prefix v8-315)
You are replacing the current local value of build.therubyracer, which is currently nil
$ bundle install

mysql2がインストールできない

以下の記事と同じことを行ったらインストールできた。

$ bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib --with-cppflags=-I/usr/local/opt/openssl/include"
$ bundle install

[参考]
[MacOS Mojave]mysql2のbundle installに失敗してハマった件 - Qiita
macOS Mojave環境でmysql2(0.5.2)のgemインストールが失敗した - Qiita

bundle exec rails serverでエラーがでる。

上述したエラーを全て回避し、bundle installは全て成功したのに、rails sでまさかのエラー。
以下の記事の参考にして、なんとか対応できた。

bundle updateするしかなかったのにで以下のコマンドで対応

$ bundle update therubyracer

【Ruby on Rails】dyld: lazy symbol binding failed: Symbol not found: というエラーが出たので - ハイパーニートプログラマーへの道

そしてついにサーバが立ち上がった!と思ったら・・・

最後に、Ignoring・・・という変なログがサーバを立ち上げたら出てきた。。。
サーバ自体はちゃんと立ち上がるようになったら、起動する度にこのエラーを見たくないので
gemがインストールされているフォルダを見に行き、ignoring・・・のgemのgemspecを削除することで
このメッセージを強制的に出ないようにした。

※色んなサイトには「gem pristine --all」しろと書いてあるが、だめだった。

場所: /vendor/bundle/ruby/2.3.0/specifications

[参考]
ruby - Ignoring GEM because its extensions are not built - Stack Overflow