背景
とある教材を見ながらプロジェクトを作成していたところ、bundle install を実行したらエラーが発生したのでメモ。
「Mysqlの導入で発生したエラー解消」という内容で、最終的に「bundleのオプション指定」することにより解消できた。
実行したコマンド
$ rails new myapp --database=mysql --skip-bundle --skip-test
$ cd myapp
$ bundle install
エラー内容
(省略)
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
(省略)
linking shared-object mysql2/mysql2.bundle
ld: library not found for -lssl
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mysql2.bundle] Error 1
make failed, exit code 2
Gem files will remain installed in /var/folders/mj/93db0vd975799gg9w3nnr3_r0000gn/T/bundler20190503-14531-xlyd6cmysql2-0.5.2/gems/mysql2-0.5.2 for inspection.
Results logged to /var/folders/mj/93db0vd975799gg9w3nnr3_r0000gn/T/bundler20190503-14531-xlyd6cmysql2-0.5.2/extensions/universal-darwin-18/2.3.0/mysql2-0.5.2/gem_make.out
An error occurred while installing mysql2 (0.5.2), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.5.2'` succeeds before bundling.
In Gemfile:
mysql2
考えたこと
- そういえばプロジェクト作成のときにDBをmysqlで指定したのは始めてだな。
- mysql2 0.5.2 をインストールできないということかな。
-
gem install mysql2 -v '0.5.2'
を実行しなさいと言ってるのかしら? - Gemfile でmysql2 のバージョンは何になってる?
- ひとまずググるか。
やったこと
Gemfile の確認
gem 'mysql2', '>= 0.3.18', '< 0.6.0'
Gemfile 内の記述は以下の通り。
ダメな部分があるか否かが不明のため、ひとまず確認のみ。
エラーログに記載されているコマンドを実行
$ gem install mysql2 -v '0.5.2'
ERROR: While executing gem ... (Gem::FilePermissionError)
You don't have write permissions for the /Library/Ruby/Gems/2.3.0 directory.
結果、エラーの解消にはつながらなかった。
ググる!→このコマンドでエラー解消!【解決】
エラーの原因特定、解消方法を調べてみたところ、下記コマンド実行にて解決した。
$ bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib"
$ bundle install
※追記:解消方法コマンド1行目に$ bundle config --local build.mysql2 "--with-cppflags=-I/usr/local/opt/openssl/include"
という記述をしておりましたが、後で実行されるコマンドで上書きされるため不要ということがわかり削除しました。(@keik 様、ご指摘いただきありがとうございます)
その後、下記コマンドを実行することで「You’re on Rails」画面を開くことができたので今回のエラーは解決とする。
$ rails db:create
$ rails s
原因・学び
今回のエラー解消に際し、色々と調べる中で学んだことをメモ。
エラーについて
どうやら、今回は下記エラーログがポイントだった模様。
ld: library not found for -lssl
原因を言語化すると、opensslのパスがビルドの時に必要(ビルドのときにLDFLAGSとかCPPFLAGSとかにパスを追加する記述が必要)ということ。
ld とは?
ld
はGNUリンカーと呼ばれるコマンドとのこと。$ man ld
で内容を確認できる。
-lssl
は、mysql2 gemインストール時にld
コマンドに与えられたオプションの一つらしい。
ここでは詳細の掘り下げはせずに置いておく。。
解決策について
bundle config とは?
下記ページにて詳細を確認する事ができた。
http://ruby.studio-kingdom.com/bundler/bundle_config/
コマンドbundle config
により、Bundlerの設定システムを操作することができるとのこと。
なお、 Bundlerは自身の設定を下記の優先順位で取得する。
1. ローカルのアプリケーション(app/.bundle/config
)
2. 環境変数
3. ユーザーのホームディレクトリ(~/.bundle/config
)
また、--local
オプションをつけることで、ローカルのアプリケーションに対して設定が可能。つまりプロジェクト単位の設定となる。
宿題
- bundle config で指定する「LDFLAGS」「CPPFLAGS」についてもう少し調べるべし。
- ld コマンドについてももう少し。(仮)