Railsでmysql2 gemをインストールするときにエラーがでたときの対処法【error】

イヌ
イヌ

なんでか、mysql2はエラーが出がちですね!
native関係のエラーは辛いですね!

ウサギ
ウサギ

何言ってるか全然わからないけど、知ってる人には届くと信じてる!

bundle install時にエラーが発生

よくありますね。bundle install時に、

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
Code language: CSS (css)

とてもハマる予感がするエラー。つらい。

今回はmysql2です。以下のようにbundle installすると、

$ bundle install Fetching gem metadata from https://rubygems.org/....... ... 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/your-username/rails-project-name/vendor/bundle/ruby/2.5.0/gems/mysql2-0.5.2/ext/mysql2 /Users/your-username/.anyenv/envs/rbenv/versions/2.5.5/bin/ruby -r ./siteconf20201026-16291-hwa1f6.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/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... no ----- 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/Cellar/mysql/8.0.22/lib ----- creating Makefile current directory: /Users/your-username/rails-project-name/vendor/bundle/ruby/2.5.0/gems/mysql2-0.5.2/ext/mysql2 make "DESTDIR=" clean current directory: /Users/your-username/rails-project-name/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: 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/your-username/rails-project-name/vendor/bundle/ruby/2.5.0/gems/mysql2-0.5.2 for inspection. Results logged to /Users/your-username/rails-project-name/vendor/bundle/ruby/2.5.0/extensions/x86_64-darwin-19/2.5.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
Code language: PHP (php)

インストールエラー。悲しい。

上記エラーを見ると

ld: library not found for -lssl
Code language: HTTP (http)

とあるので、ssl関連のライブラリが見つからない。とのこと。

そうです。OpenSSLです。

なぜOpenSSLのnativeエラーがでてしまうのか

MacOSのHigh Sierra以降、デフォルトのopensslコマンドが、OpenSSLではなくLibreSSLになったからです。

OpenSSLはheartbleedという世間を騒がせた脆弱性が発見されたのを契機に、Appleが置き換えたようですね。いや大騒ぎでした、業界では。

参考 ハートブリードWikipedia

ということで、イヌのNew GearであるMacのバージョンを調べると以下です。

$ sw_vers ProductName: Mac OS X ProductVersion: 10.15.7 BuildVersion: 19H2

で、opensslコマンドのバージョンも調べてみると。

$ openssl version LibreSSL 2.8.3

はい、LibreSSLですね。

mysql2 gemでは、LibreSSLは想定されていないため、ビルドを走らせる際に「対象のSSLライブラリが無いんだけど?」というエラーが出たというわけです。

OpenSSLのインストール

ということで、opensslをインストールしてきましょう。

$ brew install openssl Updating Homebrew... ==> Auto-updated Homebrew! Updated 1 tap (homebrew/cask-versions). No changes to formulae. ==> Downloading https://homebrew.bintray.com/bottles/openssl%401.1-1.1. ==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/4e5357c0cfd5 ######################################################################## 100.0% ==> Pouring openssl@1.1-1.1.1h.catalina.bottle.tar.gz ==> 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 '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" ==> Summary 🍺 /usr/local/Cellar/openssl@1.1/1.1.1h: 8,067 files, 18.5MB
Code language: PHP (php)

はい、完了しました。

続いてPathを通すために以下のコマンドを叩きます。

$ echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc $ source ~/.zshrc
Code language: PHP (php)

.zshrcの末尾に、'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"'を追加して、Pathを通します。

source ~/.zshrcでshellを再読み込みです。

確認すると、OpenSSLになってますね。OK。

$ openssl version OpenSSL 1.1.1h 22 Sep 2020

続いて、gemのmysql2をbuildするときに、きちんと今インストールしたOpenSSLのライブラリを参照するようにbuild optionを追加します。

参照する部分は以下のところですね。

export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
Code language: JavaScript (javascript)

以下をconfigに設定すればOKです。

$ bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl@1.1/lib"
Code language: JavaScript (javascript)

確認をすると、build.mysq2の項目に、セットしたフラグが表示されていることがわかります。

$ bundle config --local Settings are listed in order of priority. The top value will be used. build.mysql2 Set for your local app (/Users/your-username/rails-project-name/.bundle/config): "--with-ldflags=-L/usr/local/opt/openssl@1.1/lib"
Code language: JavaScript (javascript)

改めて、インストール。

$ bundle install ... Installing mysql2 0.5.2 with native extensions Bundle complete! 999 Gemfile dependencies, 999 gems now installed.b
Code language: JavaScript (javascript)

無事インストール完了しました!よかったよかった。

補足

2つ目のフラグccpflagsも一緒にオプションを渡すと、エラーになるのでNGです

$ bundle config --local build.mysql2 "--with-cppflags=-I/usr/local/opt/openssl@1.1/include --with-cppflags=-I/usr/local/opt/openssl@1.1/include"
Code language: JavaScript (javascript)
イヌ
イヌ

nativeインストール周りは大変なことが多いけど、なにか参考になれば幸いです!

ウサギ
ウサギ

解決したなら良かった!

またね〜

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です