状況
macOS catalina で railsアプリの開発環境を整え終わって、
Windows10環境で開発してたWebアプリをクローンし、いざrails server
実行だ!
と意気込んでいたら、見た事のないエラーに困惑…
解決はできたものの、いろいろと調べたら闇が深そうだったので、
自分用にメモを残しておきます。
ついでに同じエラーに悩む方の助けになれば幸いです!
エラー内容
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でインストールを行いますが、
Homebrewのインストール方法については、他で調べれば記事が大量だと思うのでここでは割愛させていただきます!
※Homebrewの利用にはXcodeが必須となりますので、インストールしていない方は先にインストールしておきましょう。
既にHomebrewをインストール済みの方は、以下のコマンドを実行します。
% brew install openssl@1.1
インストールが完了したら、brew info openssl
を実行します。
するとOpenSSL@1.1
について以下のような情報が表示されます。
% 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から下記コマンドを実行します。
※特定のアプリにのみビルドオプションを指定したい場合は、該当アプリのルートディレクトリにいる状態でローカルの方のコマンドを実行してください!
#グローバル(別のアプリで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を削除します。
% bundle exec gem uninstall mysql2
bundle install を実行
既にbundle config
でビルドオプションを設定済みですので、bundle install
若しくはbundle
のみでインストール可能です。
% bundle install
これで、ロードエラーが解消され、正常にサーバーが起動されると思います。
デフォルトSSLをLibreSSLに戻したい時
デフォルトSSLをLibreSSLに戻したい場合は、~/.zshrc
に追加された
export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"
を削除・保存し、zshを再起動すると、
LibreSSLがデフォルトSSLに戻ります。