🦁

An error occurred while installing mysql2 (0.5.3), M1 Mac

2022/02/08に公開

An error occurred while installing mysql2 (0.5.3), and Bundler cannot continue.Make sure that gem install mysql2 -v '0.5.3' --source 'https://rubygems.org/' succeeds before bundling.

rails7でbundle installしようとしたらハマって、
なかなか記事が見つけられなかったので作成することにしました。

以下のコマンドで解決した人しなかった人向けの記事です

$ bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib"
$ bundle install

一番下のまとめがあるので、端折りたい人は下までスクロールしてください

開発環境

MacBook Pro(14インチ、2021)
Apple M1 Pro
ローカル
Ruby 3.0.1
Rails 7.0.1

mysql 0.5.3がinstallできなかった

上記でも書いたようにrails7でbundle installしたら、mysql2(0.5.3)がインストールできませんでした。

$ bundle install
..
..
linking shared-object mysql2/mysql2.bundle
ld: library not found for -lssl
ld: library not found for -lzstd
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.3/gems/mysql2-0.5.3 for inspection.
Results logged to /var/folders/mj/93db0vd975799gg9w3nnr3_r0000gn/T/bundler20190503-14531-xlyd6cmysql2-0.5.3/extensions/universal-darwin-18/2.3.0/mysql2-0.5.2/gem_make.out


An error occurred while installing mysql2 (0.5.3), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.5.3'` succeeds before bundling.

In Gemfile:
  mysql2

とりあえず、エラーに書かれていたので
gem install mysql2 -v '0.5.3'
を実行

$ gem install mysql2 -v '0.5.3'
Building native extensions. This could take a while...
ERROR:  Error installing mysql2:
	ERROR: Failed to build gem native extension.

    current directory: /Users/kosuke/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/mysql2-0.5.3/ext/mysql2
/Users/kosuke/.rbenv/versions/3.0.1/bin/ruby -I /Users/kosuke/.rbenv/versions/3.0.1/lib/ruby/3.0.0 -r ./siteconf20220203-35588-2amaid.rb extconf.rb
checking for rb_absint_size()... yes
checking for rb_absint_singlebit_p()... yes
checking for rb_wait_for_single_fd()... yes
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
...
..
.

調べてみると、どうやらAppleの独自暗号化ライブラリが優先して使用されるからgemをinstallしてビルドする際に、互換性のあるopensslを使用しなければいけないらしい...?

homebrew の mysql ライブラリは homebrew の openssl を使ってビルドされていて、それを gem i mysql2 でも使いたいけど、homebrew の openssl は /usr/local (or /opt/homebrew )に symlink が貼られておらず gem install では見つけることができないので ldflag を指定する

とりあえず、確認

$ openssl version
LibreSSL 2.8.3

opensslじゃないものが入ってる
→High SierraからデフォルトがOpenSSLからLibreSSLに変更されたらしい

LibreSSLからOpenSSLに変更

まずはLibreSSLが悪さをしているので、OpenSSLに変更する

$ brew link --force openssl@1.1
Linking /opt/homebrew/Cellar/openssl@1.1/1.1.1m... 3989 symlinks created.

If you need to have this software first in your PATH instead consider running:
  echo 'export PATH="/opt/homebrew/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc
  
  
# ~/.zshrcに以下のパスを追加
$ echo 'export PATH="/opt/homebrew/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc
$ source ~/.zshrc
$ openssl version
OpenSSL 1.1.1m

これでOpenSSLに変わった

bundle configのパス変更

その後にbundle configにmysqlをbuildするためのパスを追加

$ brew info openssl@1.1
openssl@1.1: stable 1.1.1m (bottled) [keg-only]
Cryptography and SSL/TLS Toolkit
https://openssl.org/
/opt/homebrew/Cellar/openssl@1.1/1.1.1m (8,081 files, 18MB) *
  Poured from bottle on 2022-01-18 at 19:26:24
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/openssl@1.1.rb
License: OpenSSL
==> Dependencies
Required: ca-certificates ✔
==> Caveats
A CA file has been bootstrapped using certificates from the system
keychain. To add additional certificates, place .pem files in
  /opt/homebrew/etc/openssl@1.1/certs

and run
  /opt/homebrew/opt/openssl@1.1/bin/c_rehash

openssl@1.1 is keg-only, which means it was not symlinked into /opt/homebrew,
because macOS provides LibreSSL.

If you need to have openssl@1.1 first in your PATH, run:
  echo 'export PATH="/opt/homebrew/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc

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

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

==> Analytics
install: 855,084 (30 days), 2,889,680 (90 days), 10,383,915 (365 days)
install-on-request: 25,446 (30 days), 83,602 (90 days), 642,883 (365 days)
build-error: 719 (30 days)


$ bundle config --local build.mysql2 "--with-ldflags=-L/opt/homebrew/opt/openssl@1.1/lib


$ bundle install
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
..
..
..
2 warnings generated.
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/'
ld: library not found for -lzstd
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mysql2.bundle] Error 1

make failed, exit code 2

..
..

An error occurred while installing mysql2 (0.5.3), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.5.3' --source 'https://rubygems.org/'` succeeds before bundling.

In Gemfile:
  mysql2

まだいけない

他の解決策を探している中でLIBRARY_PATHを設定しているものがあった
https://github.com/brianmario/mysql2/issues/795#issuecomment-861871957

※ 以下は最終的に要らないので打ち込まないでください

$ export LIBRARY_PATH=$LIBRARY_PATH:/opt/homebrew/Cellar/openssl@3/lib

$ bundle install
...
..
2 warnings generated.
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/'
ld: warning: directory not found for option '-L/opt/homebrew/Cellar/openssl@3/lib'
ld: library not found for -lzstd
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mysql2.bundle] Error 1

make failed, exit code 2

..
..

An error occurred while installing mysql2 (0.5.3), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.5.3' --source 'https://rubygems.org/'` succeeds before bundling.

In Gemfile:
  mysql2

ld: library not found for -lzstdのエラーが消えない

無駄な環境変数の削除

上記のログに他の手順で無駄な環境変数を追加してしまっていて、
warningが出ていたので一先ず、消すことにした

ld: warning: directory not found for option '-L/usr/local/opt/openssl/lib/'
ld: warning: directory not found for option '-L/opt/homebrew/Cellar/openssl@1.1/1.1.1k/lib'
ld: library not found for -lzstd
# 環境変数一覧コマンド
$ export -p
..
...
export LIBRARY_PATH=:/usr/local/opt/openssl/lib/:/opt/homebrew/Cellar/openssl@1.1/1.1.1k/lib:/opt/homebrew/Cellar/openssl@3/3.0.1/lib/
...
..

以下のコマンドで消す

$ unset LIBRARY_PATH

正しいLIBRARY_PATHの設定

$ export LIBRARY_PATH=$LIBRARY_PATH:/opt/homebrew/Cellar/zstd/1.5.2/lib:/opt/homebrew/Cellar/openssl@1.1/1.1.1m/lib/

zstdのパスとopensslのパスの両方が必要だった
もう一度エラーを見返そう
ld: library not found for -lzstd
-lzstd
答えはエラーの中に書いてあった...orz

  • zstdとは?
    • 圧縮形式Zstandard
    • Facebookがオープンソース化した圧縮アルゴリズムライブラリ
  • Cellarとは?
    • インストール先。brew install でインストールしたパッケージがある場所。

https://qiita.com/01en/items/6cfc542c52f1853019d6

まとめ

一番最初に出ていたエラーに書かれていた

ld: library not found for -lssl
ld: library not found for -lzstd

1つ目がOpenSSLが原因で、2つ目はzstdが原因だったようです。
最初からエラーに答えは書いてあったという...

$ brew install openssl
$ echo 'export PATH="/opt/homebrew/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc
$ source ~/.zshrc
$ bundle config --local build.mysql2 "--with-ldflags=-L/opt/homebrew/opt/openssl@1.1/lib"
$ export LIBRARY_PATH=$LIBRARY_PATH:/opt/homebrew/Cellar/zstd/1.5.2/lib:/opt/homebrew/Cellar/openssl@1.1/1.1.1m/lib/

ruby3.1の場合は、

$ brew install openssl
$ echo 'export PATH="/opt/homebrew/opt/openssl@3/bin:$PATH"' >> ~/.zshrc
$ source ~/.zshrc
$ bundle config --local build.mysql2 "--with-ldflags=-L/opt/homebrew/opt/openssl@3/lib"
$ export LIBRARY_PATH=$LIBRARY_PATH:/opt/homebrew/Cellar/zstd/1.5.2/lib:/opt/homebrew/Cellar/openssl@3/3.0.1/lib/

参考

https://qiita.com/tatama/items/5e6c7c0ba1a2ba7ff9d3

https://qiita.com/halo57/items/e7511f3befbcb9fedd6a

https://www.blog.umentu.work/rails-openssl-zstd-error/

https://qiita.com/P-man_Brown/items/bb525958f361af39a472

Discussion