【Rails】MySQL2がbundle installできない時の対応方法

railsプロジェクト作成の際に、
「railsインストールして`rails new`したし、次は`bundle install`だなー」
と思い`bundle install`したのですが、がっつりエラーが発生しました。

結構時間が取られてしまったので、備忘録として対応方法を記載しておきたいと思います。

# 起こったこと
`bundle install`実行時に下記のエラーが出てきました。

```console
$ bundle install

(色々なgemのインストールのログが出てくる）
.
.
.
Installing ...
Fetching mysql2 0.5.2
Installing mysql2 0.5.2 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    current directory: /Users/fukudatakumi/tabelog/vendor/bundle/ruby/2.5.0/gems/mysql2-0.5.2/ext/mysql2
/Users/fukudatakumi/.rbenv/versions/2.5.1/bin/ruby -I /Users/fukudatakumi/.rbenv/versions/2.5.1/lib/ruby/site_ruby/2.5.0 -r ./siteconf20190321-35638-onb5bd.rb extconf.rb
--with-opt-lib\=/usr/local/opt/openssl/lib\ --with-opt-include\=-I/usr/local/opt/openssl/include
checking for rb_absint_size()... yes
checking for rb_absint_singlebit_p()... yes
checking for rb_wait_for_single_fd()... yes
-----
Using mysql_config at /usr/local/opt/mysql@5.7/bin/mysql_config
-----
checking for mysql.h... yes
checking for errmsg.h... yes
checking for SSL_MODE_DISABLED in mysql.h... yes
checking for SSL_MODE_PREFERRED in mysql.h... yes
checking for SSL_MODE_REQUIRED in mysql.h... yes
checking for SSL_MODE_VERIFY_CA in mysql.h... yes
checking for SSL_MODE_VERIFY_IDENTITY in mysql.h... yes
checking for MYSQL.net.vio in mysql.h... yes
checking for MYSQL.net.pvio in mysql.h... no
checking for MYSQL_ENABLE_CLEARTEXT_PLUGIN in mysql.h... yes
checking for SERVER_QUERY_NO_GOOD_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_NO_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_WAS_SLOW in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_ON in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_OFF in mysql.h... yes
checking for my_bool in mysql.h... yes
-----
Don't know how to set rpath on your system, if MySQL libraries are not in path mysql2 may not load
-----
-----
Setting libpath to /usr/local/opt/mysql@5.7/lib
-----
creating Makefile

current directory: /Users/fukudatakumi/tabelog/vendor/bundle/ruby/2.5.0/gems/mysql2-0.5.2/ext/mysql2
make "DESTDIR=" clean

current directory: /Users/fukudatakumi/tabelog/vendor/bundle/ruby/2.5.0/gems/mysql2-0.5.2/ext/mysql2
make "DESTDIR="
compiling client.c
compiling infile.c
compiling mysql2_ext.c
compiling result.c
compiling statement.c
linking shared-object mysql2/mysql2.bundle
ld: warning: directory not found for option '-L/usr/local/opt/openssl/lib --with-opt-include=-I/usr/local/opt/openssl/include'
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 /Users/fukudatakumi/tabelog/vendor/bundle/ruby/2.5.0/gems/mysql2-0.5.2 for inspection.
Results logged to /Users/fukudatakumi/tabelog/vendor/bundle/ruby/2.5.0/extensions/x86_64-darwin-18/2.5.0-static/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' --source 'https://rubygems.org/'` succeeds before bundling.
```

前までエラー出なかったのに、なんじゃこりゃ…

#やってみたこと
##1 とりあえずエラーコードに、下記を実行しろと書いてあるのでしてみる。
一番下の行に書いてある`Make sure that~`の部分ですね。やってみます。

```console
$ gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/'

ERROR:  While executing gem ... (Errno::EACCES)
    Permission denied @ rb_sysopen - /Users/fukudatakumi/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/mysql2-0.5.2/CHANGELOG.md
```

権限ないから実行できないよと言われてしまう。（Permission denied）

##2 権限付与してやってみる。
`sudo`付けて実行してみる。

```console
$ sudo gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/'

Building native extensions. This could take a while...
ERROR:  Error installing mysql2:
	ERROR: Failed to build gem native extension.

    current directory: /Users/fukudatakumi/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/mysql2-0.5.2/ext/mysql2
/Users/fukudatakumi/.rbenv/versions/2.5.1/bin/ruby -I /Users/fukudatakumi/.rbenv/versions/2.5.1/lib/ruby/site_ruby/2.5.0 -r ./siteconf20190321-41125-u1s6ei.rb extconf.rb
checking for rb_absint_size()... yes
checking for rb_absint_singlebit_p()... yes
checking for rb_wait_for_single_fd()... yes
-----
Using mysql_config at /usr/local/opt/mysql@5.7/bin/mysql_config
-----
checking for mysql.h... yes
checking for errmsg.h... yes
checking for SSL_MODE_DISABLED in mysql.h... yes
checking for SSL_MODE_PREFERRED in mysql.h... yes
checking for SSL_MODE_REQUIRED in mysql.h... yes
checking for SSL_MODE_VERIFY_CA in mysql.h... yes
checking for SSL_MODE_VERIFY_IDENTITY in mysql.h... yes
checking for MYSQL.net.vio in mysql.h... yes
checking for MYSQL.net.pvio in mysql.h... no
checking for MYSQL_ENABLE_CLEARTEXT_PLUGIN in mysql.h... yes
checking for SERVER_QUERY_NO_GOOD_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_NO_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_WAS_SLOW in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_ON in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_OFF in mysql.h... yes
checking for my_bool in mysql.h... yes
-----
Don't know how to set rpath on your system, if MySQL libraries are not in path mysql2 may not load
-----
-----
Setting libpath to /usr/local/opt/mysql@5.7/lib
-----
creating Makefile

current directory: /Users/fukudatakumi/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/mysql2-0.5.2/ext/mysql2
make "DESTDIR=" clean

current directory: /Users/fukudatakumi/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/mysql2-0.5.2/ext/mysql2
make "DESTDIR="
compiling client.c
compiling infile.c
compiling mysql2_ext.c
compiling result.c
compiling statement.c
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 /Users/fukudatakumi/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/mysql2-0.5.2 for inspection.
Results logged to /Users/fukudatakumi/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/extensions/x86_64-darwin-18/2.5.0-static/mysql2-0.5.2/gem_make.out
```

またもやエラー。しかもなんか難しそう…

##3 エラー内容ググる。
結論から言うと、下記３記事を参考にして解決しました。（先人の知恵ありがたし…）
[mysql2 gemインストール時のトラブルシュート](https://qiita.com/HrsUed/items/ca2e0aee6a2402571cf6)
[RailsプロジェクトでMySQLがbundle installできなかった](https://qiita.com/akito19/items/e1dc54f907987e688cc0)
[bundle install 時、mysql2でエラー](https://qiita.com/tktcorporation/items/0ef8c930fc18ce72c301)

めちゃめちゃ簡単にまとめると、

- LDFLAGSとかCPPFLAGSとやらをオプション指定した上で`bundle install`すればいい。.
- 設定するべき値は`brew info openssl`で確認できる。

といった感じです。

##4 対応方法
自分の場合は、下記の順番に行っていけば解決できました！

```console
$ brew info openssl

openssl: stable 1.0.2q (bottled) [keg-only]
SSL/TLS cryptography library
https://openssl.org/
/usr/local/Cellar/openssl/1.0.2o_2 (1,792 files, 12.3MB)
  Poured from bottle on 2018-07-11 at 08:41:25
/usr/local/Cellar/openssl/1.0.2p (1,793 files, 12.3MB)
  Poured from bottle on 2018-09-02 at 01:23:21
/usr/local/Cellar/openssl/1.0.2q (1,794 files, 12.1MB)
  Poured from bottle on 2018-12-24 at 15:14:30
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/openssl.rb
==> Caveats
A CA file has been bootstrapped using certificates from the SystemRoots
keychain. To add additional certificates (e.g. the certificates added in
the System keychain), place .pem files in
  /usr/local/etc/openssl/certs

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

openssl is keg-only, which means it was not symlinked into /usr/local,
because Apple has deprecated use of OpenSSL in favor of its own TLS and crypto libraries.

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

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

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

==> Analytics
install: 444,212 (30 days), 1,417,472 (90 days), 6,155,261 (365 days)
install_on_request: 53,063 (30 days), 186,506 (90 days), 864,296 (365 days)
build_error: 0 (30 days)
```

下の部分が重要。

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

path確認して

```console
$ bundle config --local build.mysql2 "--with-cppflags=-I/usr/local/opt/openssl/include"
$ bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib"
```
この後に

```console
$ bundle install
```

これで無事解決！

#おわりに
先人の知恵のおかげでなんとか解決できました。
ただ**LDFLAGS**や**CPPFLAGS**などの設定の意味はまだまだ理解できていないので、これから勉強しようと思います。
どなたかこの辺りの勉強にオススメのサイトや書籍を知っていたら教えてくださいませ。