13
15

More than 1 year has passed since last update.

gem mysql2がbundle installできない時の解決法(ERROR: Error installing mysql2:)

Last updated at Posted at 2021-05-15

株式会社TECH LUCKという会社で代表兼エンジニアをしている齊藤です。

RailsでMySQLを使うために、Gemfileにgem mysql2を記述し、bundle installした際に以下のようなエラーが出てきました。

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

    current directory: /Users/test/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/mysql2-0.4.5/ext/mysql2
/Users/test/.rbenv/versions/2.3.1/bin/ruby -r ./siteconf20210514-68423-q7xfp2.rb extconf.rb
checking for rb_absint_size()... yes
checking for rb_absint_singlebit_p()... yes
checking for ruby/thread.h... yes
checking for rb_thread_call_without_gvl() in ruby/thread.h... yes
checking for rb_thread_blocking_region()... no
checking for rb_wait_for_single_fd()... yes
checking for rb_hash_dup()... yes
checking for rb_intern3()... yes
checking for rb_big_cmp()... yes
-----
Using mysql_config at /usr/local/opt/mysql@5.7/bin/mysql_config
-----
checking for mysql.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 errmsg.h... yes
checking for mysqld_error.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

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /Users/test/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/extensions/x86_64-darwin-20/2.3.0-static/mysql2-0.4.5/mkmf.log

current directory: /Users/test/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/mysql2-0.4.5/ext/mysql2
make "DESTDIR=" clean

current directory: /Users/test/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/mysql2-0.4.5/ext/mysql2
make "DESTDIR="
compiling infile.c
compiling client.c
compiling mysql2_ext.c
compiling statement.c
compiling result.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/test/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/mysql2-0.4.5 for inspection.
Results logged to /Users/test/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/extensions/x86_64-darwin-20/2.3.0-static/mysql2-0.4.5/gem_make.out

この対処法を備忘録として残しておきます。

システム環境

MacOS Big Sur:v11.2.3
Ruby:v2.3.1
Ruby on Rails:v5.0.0
MySQL:v5.7(Homebrewでインストール)

解決法

以下のコマンドを実行して出てくる、LDFLAGSとLDFLAGSのパスを確認します。

brew info openssl

自分の環境では以下の出力がでてくる。(シェルにfishを使っているので、デフォルトのシェルや他のシェルを使っている人とは違う形式で出力されているかもしれません。)

openssl@1.1: stable 1.1.1k (bottled) [keg-only]
Cryptography and SSL/TLS Toolkit
https://openssl.org/
/usr/local/Cellar/openssl@1.1/1.1.1k (8,071 files, 18.5MB)
  Poured from bottle on 2021-03-30 at 18:44:50
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/openssl@1.1.rb
License: OpenSSL
==> 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 macOS provides LibreSSL.

If you need to have openssl@1.1 first in your PATH, run:
  echo 'set -g fish_user_paths "/usr/local/opt/openssl@1.1/bin" $fish_user_paths' >> ~/.config/fish/config.fish

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

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

==> Analytics
install: 782,442 (30 days), 2,633,871 (90 days), 8,812,477 (365 days)
install-on-request: 58,424 (30 days), 257,430 (90 days), 1,140,537 (365 days)
build-error: 0 (30 days)

ここで注目するのは、For compilers to find openssl@1.1 you may need to set:
と記述されているところの、ダブルクーテーションで囲まれているパス。
上記の表示だと以下のパスになります。

"-L/usr/local/opt/openssl@1.1/lib"
"-I/usr/local/opt/openssl@1.1/include"

このパスをコピーして以下のコマンドを実行します。

bundle config --local build.mysql2 "--with-ldflags={LDFLAGSに表示されているパス} --with-cppflags={CPPFLAGSに表示されているパス}"

この記事の情報をもとにすると以下のコマンドを実行します。

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

きちんと設定が反映されているかどうかはアプリケーションのルートディレクトリで以下のコマンドを実行して、ファイルの中身を確認すればわかります。

cat .bundle/config

上記を実行し、以下のように表示されれば設定はうまくできています。
※この設定は先程のbundle config --localコマンドでlocalとしているため、このプロジェクトだけに適用されるものになります。

---
BUNDLE_BUILD__MYSQL2: "--with-ldflags=-L/usr/local/opt/openssl@1.1/lib --with-cppflags=-I/usr/local/opt/openssl@1.1/include"

この設定が完了したら、bundle installを実行すれば無事にインストールすることができると思います。(解決しなかったら他の解決策を試してみてください。)

エラーの原因

なぜこのようなエラーが起こるのかというと、gem mysql2はopensslが必須となっており、opensslへのパスを設定しなければなりません。
しかし、opensslが/usr/localにリンクされてないので、bundle install実行時に--with-ldflagsでopensslのライブラリの場所を指定してあげなくてはならないとのことです。

bundle configとは

ライブラリのパスの指定の際に登場するのがbundle configです。
bundle configとは、その名の通りbundlerの設定ファイルとなっています。
Railsプロジェクトであれば、.bundle/configがそのプロジェクトの設定ファイルとなっています。
実行したbundle config --localコマンドは、このローカルの設定ファイルへ書き込みを行い、bundle install時に読み込んで設定を反映してくれます。
(globalに設定したければbundle config --globalというコマンドがあります。)

実際に、bundle config --localコマンドを実行した後に、cat .bundle/configを実行すると以下のように出力されます。

---
BUNDLE_BUILD__MYSQL2: "--with-ldflags=-L/usr/local/opt/openssl@1.1/lib --with-cppflags=-I/usr/local/opt/openssl@1.1/include"

これが設定されていることで、このプロジェクトでbundlerを使ってgem mysql2のインストールする際には、設定されている情報が読み込み反映されインストールがされます。

ちなみにbundle configについての詳細は以下になります。※英語です。
https://bundler.io/v1.13/man/bundle-config.1.html

参考にした記事(圧倒的感謝)

13
15
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
15