Library not loaded: libssl.1.1.dylib (LoadError) 発生時の解決方法

#状況

macOS catalina で railsアプリの開発環境を整え終わって、
Windows10環境で開発してたWebアプリをクローンし、いざ`rails server`実行だ！
と意気込んでいたら、見た事のないエラーに困惑…

解決はできたものの、いろいろと調べたら闇が深そうだったので、
自分用にメモを残しておきます。

ついでに同じエラーに悩む方の助けになれば幸いです！

###エラー内容
```zsh:zsh
dlopen(/Users/kirimaro/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundle, 9): Library not loaded: libssl.1.1.dylib (LoadError)
  Referenced from: /Users/kirimaro/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundle
  Reason: image not found - /Users/kirimaro/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundle
```

#`OpenSSL@1.1`のインストール

macOS catalina はデフォルトのSSLがLibreSSL 2.8.3が設定されています。
試しに`openssl version`を実行すると、`LibreSSL 2.8.3`と出力されはずです。
上記エラーの原因はこいつです。

`gem "mysql2"`はOpenSSLと依存関係にあり、LibreSSLがデフォルトだと`Library not loaded: libssl.1.1.dylib`といったロードエラーが発生します。

これを解消するために、まず`OpenSSL@1.1`をインストールします。

尚、`OpenSSL@1.1`は[Homebrew](https://brew.sh/index_ja)でインストールを行いますが、
Homebrewのインストール方法については、他で調べれば記事が大量だと思うのでここでは割愛させていただきます！
※Homebrewの利用にはXcodeが必須となりますので、インストールしていない方は先にインストールしておきましょう。

####既にHomebrewをインストール済みの方は、以下のコマンドを実行します。

```zsh:zsh
% brew install openssl@1.1
```
####インストールが完了したら、`brew info openssl`を実行します。
すると`OpenSSL@1.1`について以下のような情報が表示されます。

```zsh:zsh
% brew info openssl
openssl@1.1: stable 1.1.1d (bottled) [keg-only]
Cryptography and SSL/TLS Toolkit
https://openssl.org/
/usr/local/Cellar/openssl@1.1/1.1.1d (7,983 files, 17.9MB)
  Poured from bottle on 2020-03-30 at 20:49:11
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/openssl@1.1.rb
==> Caveats
A CA file has been bootstrapped using certificates from the system
keychain. To add additional certificates, place .pem files in
  /usr/local/etc/openssl@1.1/certs

and run
  /usr/local/opt/openssl@1.1/bin/c_rehash

openssl@1.1 is keg-only, which means it was not symlinked into /usr/local,
because openssl/libressl is provided by macOS so don't link an incompatible version.

If you need to have openssl@1.1 first in your PATH run:
  echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc

For compilers to find openssl@1.1 you may need to set:
  export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
  export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"

For pkg-config to find openssl@1.1 you may need to set:
  export PKG_CONFIG_PATH="/usr/local/opt
```

重要なのは、`echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc`で、
これをzshにコピペして実行する事で、デフォルトのSSLがOpenSSLへ変更されます。

実は、エラーの解消自体はOpenSSLをインストールしていれば、デフォルトに設定していなくても問題なく解決できます。

私自身まだそこまで詳しくないのですが、開発ツールなどの多くがまだまだOpenSSLへ依存している状況もあるようなので、
デフォルトに指定しておいたほうが無難なのかなと思います。

正しく切り替わったか確認したい場合は、zshを再起動したうえで`openssl version`を入力してみて下さい。
`OpenSSL @1.1.1d`といった感じで、デフォルトSSLが切り替わっている事が確認できると思います。

#`mysql2`ビルド時に必要となるlib/includeのPathを環境変数に追加

`~/.zshenv`ファイルをviなどのテキストエディタで開き、
`brew info openssl`実行時に表示される下記パスを追加します。

保存したら反映するために、zshを再起動します。

```
export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"
```

#bundle configにビルドパスを追加

railsアプリのルートディレクトリへ移動し、zshから下記コマンドを実行します。
※特定のアプリにのみビルドオプションを指定したい場合は、該当アプリのルートディレクトリにいる状態でローカルの方のコマンドを実行してください！

```zsh:zsh
#グローバル（別のアプリでmysql2をインストールする場合も、ビルドオプションが適用される）
% bundle config build.mysql2 --with-ldflags=$LDFLAGS --with-cppflags=$CPPFLAGS

#ローカル（現在ルートディレクトリとなっているアプリでのみ、mysql2インストール時にビルドオプションが渡される）
% bundle config --local build.mysql2 --with-ldflags=$LDFLAGS --with-cppflags=$CPPFLAGS
```
これで、bundle installを実行した際、mysql2のインストール時にビルドオプションとして、opensslのlib/includeが読み込まれます。

#Railsアプリからすでにインストール済みの`mysql2`をアンインストール

下記コマンドを実行し、インストール済みのmysql2を削除します。

```zsh:zsh
% bundle exec gem uninstall mysql2
```
#bundle install を実行

既に`bundle config`でビルドオプションを設定済みですので、`bundle install`若しくは`bundle`のみでインストール可能です。

```zsh:zsh
% bundle install
```

これで、ロードエラーが解消され、正常にサーバーが起動されると思います。

#デフォルトSSLをLibreSSLに戻したい時

デフォルトSSLをLibreSSLに戻したい場合は、`~/.zshrc`に追加された
`export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"`を削除・保存し、zshを再起動すると、
LibreSSLがデフォルトSSLに戻ります。