18
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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: 備考: 未宣言の識別子は出現した各関数内で一回のみ報告されます

やっぱり分からんて。

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

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

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

18
8
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
18
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?