0
0

Ruby3.0系から3.1系へのバージョンアップ

Last updated at Posted at 2024-07-28

背景

Ruby3.0.6とRails6.1.7.7で開発したアプリを運用します。デプロイ先はheroku(heroku-20)で特に問題なくアプリは動いていました。

しかしながら、Ruby3.0系はheroku-20と互換性はありますが、heroku-22と互換性がなく、Ruby3.0系でherokuにデプロイしようとすると以下のエラーが発生しました。

remote: This app is using the Heroku-20 stack, which is deprecated:
remote: https://devcenter.heroku.com/changelog-items/2895
remote: 
remote: From April 30th 2025, Heroku-20 will be end-of-life, and apps using it
remote: will no longer receive security updates, and be run at your own risk.
remote: 
remote: From May 1st 2025, builds will no longer be allowed for Heroku-20 apps.
remote: 
remote: Please upgrade to a newer stack as soon as possible:

そこで、Ruby3.0.6からRuby3.1.0へのバージョンアップを試みました。
マイナーバージョンアップにも関わらずエラーが頻繁に発生しました。
みなさんの参考になれば嬉しいです。

現在のバージョン

Ruby:3.6.0
Rails:6.1.7.7
bundler:2.5.3、2.4.13(default:2.4.13)
node:16.20.0
npm:8.19.4
yarn:1.22.19
webpack:4.46.0
※開発環境は、macOS Monterey バージョン12.1です。
※エディターは、VSCodeを使用しています。
※デプロイ先は、herokuです。

今回のアップデート

ruby:3.0.6⇨3.1.0

最初に試したこと

#rubyを3.1.0へのバージョンアップ
rvm install 3.1.0 --with-openssl-dir=$(brew --prefix openssl@1.1)

#「.ruby-version」ファイルへの追記
ruby '3.1.0'

#「Gemfile」ファイルへの追記
ruby '3.1.0'

#「bundle install」の実行
bundle install

発生したエラー

warning: a function declaration
without a prototype is deprecated
in all versions of C and is not
supported in C2x
[-Wdeprecated-non-prototype]
mysql2_mysql_enc_name_to_rb_hash
(str, len)
^
./mysql_enc_name_to_ruby.h:86:1:
warning: a function declaration
without a prototype is deprecated
in all versions of C and is not
supported in C2x
[-Wdeprecated-non-prototype]
mysql2_mysql_enc_name_to_rb (str,
len)
^
client.c:1438:3: error: call to
undeclared function
'mysql_ssl_set'; ISO C99 and later
do not support implicit function
declarations
[-Wimplicit-function-declaration]
  mysql_ssl_set(wrapper->client,
  ^
client.c:1438:3: note: did you
mean 'mysql_close'?
/opt/homebrew/Cellar/mysql/8.3.0_1/include/mysql/mysql.h:797:14:
note: 'mysql_close' declared here
void STDCALL mysql_close(MYSQL
*sock);
             ^
2 warnings and 1 error generated.
make: *** [client.o] Error 1

make failed, exit code 2

(省略)

An error occurred while
installing mysql2 (0.5.5), and
Bundler cannot continue.

In Gemfile:
  mysql2

対処方法

まずはMy SQLとopenssl@1.1をインストールし直しました。

brew install mysql
brew install openssl@1.1

次いで、mysql2 の gemをインストールしました。

gem install mysql2 -- --with-mysql-config=$(brew --prefix mysql)/bin/mysql_config --with-openssl-dir=$(brew --prefix openssl@1.1)

mysql2 の gemをインストールした際には、以下のエラーが発生しました。

1 warning generated.
compiling statement.c
linking shared-object mysql2/mysql2.bundle
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

「zstd」が見つからないとのことですので、以下のコードでzstdライブラリをインストールします。

brew install zstd

必要な環境変数を設定します。

export LIBRARY_PATH=$LIBRARY_PATH:$(brew --prefix zstd)/lib/
export LDFLAGS="-L$(brew --prefix zstd)/lib"
export CPPFLAGS="-I$(brew --prefix zstd)/include"

「brew link --force openssl@1.1」を実行した際に、以下のエラーが発生しました。

Linking /opt/homebrew/Cellar/openssl@1.1/1.1.1w... 
Error: Could not symlink bin/c_rehash
Target /opt/homebrew/bin/c_rehash
is a symlink belonging to openssl@3. You can unlink it:
  brew unlink openssl@3

To force the link and overwrite all conflicting files:
  brew link --overwrite openssl@1.1

To list all files that would be deleted:
  brew link --overwrite openssl@1.1 --dry-run

エラー発生の原因は、openssl@1.1とopenssl@3の競合です。以下のコードで、openssl@3のリンクを強制的に解除、openssl@1.1のリンクを強制的に作成します。

brew unlink openssl@3
brew link --force openssl@1.1

永続的に環境設定を保持するために、以下のコードを実行します。

echo 'export LIBRARY_PATH=$LIBRARY_PATH:$(brew --prefix zstd)/lib/' >> ~/.zshrc
echo 'export LDFLAGS="-L$(brew --prefix zstd)/lib"' >> ~/.zshrc
echo 'export CPPFLAGS="-I$(brew --prefix zstd)/include"' >> ~/.zshrc
source ~/.zshrc

再度、mysql2 の gemをインストールしました。

gem install mysql2 -- --with-mysql-config=$(brew --prefix mysql)/bin/mysql_config --with-openssl-dir=$(brew --prefix openssl@1.1)

以下のようなログが発生すれば、mysql2 の gemのインストールは完了です。

Building native extensions with: '--with-mysql-config=/opt/homebrew/opt/mysql/bin/mysql_config --with-openssl-dir=/opt/homebrew/opt/openssl@1.1'
This could take a while...
Successfully installed mysql2-0.5.6
Parsing documentation for mysql2-0.5.6
Done installing documentation for mysql2 after 0 seconds
1 gem installed

「bundle install」を実行します。

bundle install

「bundle install」を実行した後に、以下のエラーが発生します。

warning: a function declaration
without a prototype is deprecated
in all versions of C and is not
supported in C2x
[-Wdeprecated-non-prototype]
mysql2_mysql_enc_name_to_rb_hash
(str, len)
^
./mysql_enc_name_to_ruby.h:86:1:
warning: a function declaration
without a prototype is deprecated
in all versions of C and is not
supported in C2x
[-Wdeprecated-non-prototype]
mysql2_mysql_enc_name_to_rb (str,
len)
^
client.c:1438:3: error: call to
undeclared function
'mysql_ssl_set'; ISO C99 and later
do not support implicit function
declarations
[-Wimplicit-function-declaration]
  mysql_ssl_set(wrapper->client,
  ^
client.c:1438:3: note: did you
mean 'mysql_close'?
/opt/homebrew/opt/mysql-client/include/mysql/mysql.h:797:14:
note: 'mysql_close' declared here
void STDCALL mysql_close(MYSQL
*sock);
             ^
2 warnings and 1 error generated.
make: *** [client.o] Error 1

make failed, exit code 2

(省略)

An error occurred while
installing mysql2 (0.5.5), and
Bundler cannot continue.

In Gemfile:
mysql2

上記のエラーの原因は、Gemfileに指定されたmysql2のバージョンが0.5.5であり、現在の環境と互換性がないことです。以下のコードで、mysqlのバージョンを0.5.5から0.5.6にアップデートします。

#Gemfileの修正
gem 'mysql2', '~> 0.5.6'

#bundle configの設定
bundle config build.mysql2 "--with-mysql-config=$(brew --prefix mysql)/bin/mysql_config --with-openssl-dir=$(brew --prefix openssl@1.1)"

再度「bundle install」を実行します。

bundle install

rmvで仕様するRubyのバージョンを指定します。

rvm use 3.1.0

#まとめ
以前、Ruby2.7からRuby3.0へのメジャーアップデート方法をまとめました。
https://qiita.com/kamakura2008/items/f9526a31fb98218ba12e

今回はRuby3.0.6からRuby3.1.0へのマイナーアップデートなので、サクッと完了するかと思いましたが、多くのエラーが発生しました。

エラーを全て取り除いた後は、以下のコードですんなりとバージョンアップが可能になります。
(Ruby 3.2.5までのバージョンアップできるのを確認できています)

##rubyを3.x.xへのバージョンアップ
rvm install 3.x.x --with-openssl-dir=$(brew --prefix openssl@1.1)

#「.ruby-version」ファイルへの追記
ruby '3.x.x'

#「Gemfile」ファイルへの追記
ruby '3.x.x'

#「bundle install」の実行
bundle install

#rvmの切り替え
rvm use 3.x.x

Rubyのバージョンアップで参考になれば嬉しいです。

0
0
0

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
0
0