LoginSignup
7

CentOS 7 に Ruby 3.1.3 がインストールできなかったら

Last updated at Posted at 2022-11-29

Ruby 3.1.3 が出たので CentOS 7 にインストールしようとしたらできなかった。
その原因と解決方法について。

現象

以下のようにして rbenv で Ruby 3.1.3 をインストールしようとした。

rbenv install 3.1.3

エラーが出てインストールできなかった(後述)。

なお,同時にリリースされた 2.7.7 はインストールできた。

(追記 2022-12-01)私は試していないが,同時にリリースされた 3.0.5 は 3.1.3 と同様だそう。

原因

CentOS 7 の gcc のバージョンが古かった。

$ gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)

gcc というのは C コンパイラーの一つ。Ruby は C(など)で書かれており,rbenv を使ってインストールする場合はこれが必要になる。

対策

devtoolset とかいうやつを入れると,新しい gcc が使えるらしい(元の gcc と共存可能)。

devtoolset-11 を入れる

現時点(2022 年 11 月)では devtoolset-11 というやつでよいようだ。以下のようにしてこれをインストールする:

sudo yum install centos-release-scl
sudo yum install devtoolset-11

しかし,これだけではだめで,scl コマンドを用いて「一時的に devtoolset-11 を有効化する」ということをしなければならないらしい。
以下のようにする

scl enable devtoolset-11 bash

enable devtoolset-11 の部分が「devtoolset-11 を有効化する」ということらしいが,重要なのはその次の bash の部分。

この第三引数には,「devtoolset-11 を有効化したうえでやりたいこと」を書くらしい。
上の記述の場合,devtoolset-11 を有効化したうえで bash のサブシェルを起動することになる。以降の操作はそのサブシェル上で行われる。exit すればそのサブシェルを抜けて,元のシェルに戻る。

このことは以下のようにして確かめられる(見やすさのため,出力の一部を省いた)。

$ gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)

$ scl enable devtoolset-11 bash
$ gcc --version
gcc (GCC) 11.2.1 20220127 (Red Hat 11.2.1-9)

$ exit
$ gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)

exit でサブシェルを抜けることで,gcc のバージョンが古いほうに戻ったことが見て取れる。

なお,やりたいことが「一つのコマンドを実行する」だけであれば,bash の代わりにそれを書けばよい。" " で囲めばスペースなどが入っていても大丈夫。
この場合,scl の実行後は devtoolset が無効の状態に戻る。
以下のようにして確かめられる(出力の一部を省略)。

$ gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)

$ scl enable devtoolset-11 "gcc --version"
gcc (GCC) 11.2.1 20220127 (Red Hat 11.2.1-9)

$ gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)

Ruby をインストールする

前節のサブシェル上で

rbenv install 3.1.3

とすると,ふつうにインストールできた。めでたし。

気をつけなければいけないのは,devtoolset は Ruby のインストールだけでなく,拡張ライブラリーのインストール時も必要,ということだ。

たとえば,Ruby の標準添付ライブラリーである cgi は,一部分が C 言語で書かれた「拡張ライブラリー」というものになっている。
これを

gem update cgi

で最新版にしようとしたとき,古い gcc だとエラーが出てインストールできない。
stringio なども同様。というか,標準添付ライブラリーって,拡張ライブラリーが多い。

gem をインストール,アップデートするたびに scl コマンドを叩くのは面倒なので,有効にしっぱなしにすることもできるようなのだが,まだ試していない。

インストール失敗時のエラー

古い gcc を使っていてインストールに失敗したときは,以下のようなエラーメッセージが出た。

To follow progress, use 'tail -f /tmp/ruby-build.20221128112424.16414.log' or pass --verbose
Downloading ruby-3.1.3.tar.gz...
-> https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.3.tar.gz
Installing ruby-3.1.3...

BUILD FAILED (CentOS Linux 7 using ruby-build 20220415-108-g4f4f307)

Inspect or clean up the working tree at /tmp/ruby-build.20221128112424.16414.uOztwE
Results logged to /tmp/ruby-build.20221128112424.16414.log

Last 10 log lines:
                                  ^
vm_core.h:1870:34: 備考: 未宣言の識別子は出現した各関数内で一回のみ報告されます
miniinit.c: トップレベル:
cc1: 警告: 認識できないコマンドラインオプション "-Wno-tautological-compare" です [デフォルトで有効]
cc1: 警告: 認識できないコマンドラインオプション "-Wno-self-assign" です [デフォルトで有効]
cc1: 警告: 認識できないコマンドラインオプション "-Wno-parentheses-equality" です [デフォルトで有効]
cc1: 警告: 認識できないコマンドラインオプション "-Wno-constant-logical-operand" です [デフォルトで有効]
cc1: 警告: 認識できないコマンドラインオプション "-Wno-cast-function-type" です [デフォルトで有効]
make: *** [miniinit.o] エラー 1
make: *** 未完了のジョブを待っています....

まあ,これ見ても素人にはなんのことかサッパリ分からん。
-Wno-tautological-compare とかでウェブ検索しても原因に行き当たらない。

で,ログファイルのありかがここには書かれているので,それを見てみる。
以下のようになっている(一部分を抜粋):

compiling dmyext.c
translating probes probes.d
In file included from vm_core.h:83:0,
                 from iseq.h:14,
                 from mini_builtin.c:3,
                 from miniinit.c:51:
thread_pthread.h:108:43: エラー: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘struct’
     RUBY_EXTERN RB_THREAD_LOCAL_SPECIFIER struct rb_execution_context_struct *ruby_current_ec;
                                           ^
In file included from iseq.h:14:0,
                 from mini_builtin.c:3,
                 from miniinit.c:51:
vm_core.h: 関数 ‘rb_current_execution_context’ 内:
vm_core.h:1870:34: エラー: ‘ruby_current_ec’ が宣言されていません (この関数内での最初の使用)
     rb_execution_context_t *ec = ruby_current_ec;
                                  ^
vm_core.h:1870:34: 備考: 未宣言の識別子は出現した各関数内で一回のみ報告されます

やっぱり分からんて。

ただ,ここに出てくるキーワードを適当に使ってウェブ検索していたら,以下の記事に行きあたった。

これでようやく原因と解決方法が分かった次第。

インストール時に「コンパイラーが古いっす」とか言ってくれればいいのになあ。

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
What you can do with signing up
7