HPCシステムズではエンジニアを募集しています。詳しくはこちらをご覧ください。
HPCシステムズのエンジニア達による技術ブログ

Tech Blog

OS付属コンパイラが古すぎて困った人へ

RHEL/CentOSについて

 これらのディストリビューションはその名の通りエンタープライズ用途に用いることを前提に作られ、サポートされています。長期に渡って運用されるシステムのために固定された仕様のまま、セキュリティ対応の修正が入れられています。バージョンが固定されていることで、仕様変更が入らないことが保証され、修正は入っても突然ソフトウエアが使えなくなる恐れはありません。しかしその反面、何年も前に策定された仕様のため、新しいソフトウエアに対応できなくなるという弊害をはらんでいます。

 RHEL6.0/7.0のリリースはそれぞれ2010年/2014年なので、10年前/5年前の仕様となっています。それは6.10/7.7がリリースされた現在でも変わりません。yum updateなどとしてアップデートしても、バグ修正された同じバージョンのソフトウエアで置き換えられるので、そうした仕様に関する不整合の解消には繋がりません。

新しいソフトウエアを動かしたい

 一方で最近開発されたソフトウエアは、最近のソフトウエア環境を前提に作られていて、使用にあたって問題となることが増えています。Python/PHPといったスクリプト言語、gcc/g++/gfortran等のコンパイラとそれに紐づくlibstdc++等のライブラリなどで問題となることが多いと思います。

 ところが、それらを直接アップデートしようとするとOSの中味を破壊することに繋がるため、システム本体とは独立にインストールして使い分ける必要がでてきます。またそれらを自前で依存関係を含めて正しくインストールし、安定運用するというのはなかなか難しいと思います。

Software Collectionとは

 こうした問題に対処するため、OS本体とは独立した形で利用可能な、需要の多い新しめのバージョンのソフトウエアパッケージを用意しようというRedhat社によるプロジェクトです。独自のリポジトリがあるので、そちらを登録することにより、yumコマンドで追加インストールが可能です。これにより、OSの環境を維持したまま最新のソフトウエアも使える様になります。省略形としてSCLと呼ばれます。

 ここではお問い合わせの多い、libstdc++11に対応したgcc/g++をCentOS7環境で使えるようにしてみます。

SCLを有効にする

 リポジトリ設定のパッケージとユーティリティをインストールすれば完了です。extrasリポジトリに入っているので、こちらを有効にしておくことを忘れないでください。

# yum install scl-utils centos-release-scl

 リポジトリにはRedhat社が提供しているものとCentOSが提供しているものがありますが、標準だと前者が一緒に入ります。次に開発環境です。devtoolsetというパッケージ群でひとまとめになっています。2019年11月現在、devtoolset-6から8まであります。それぞれgccのメジャーバージョンに対応しています。そのうちdevtoolset-9も用意されるのでしょうか?ただし、こちらを見ると分かる通り、6と7は既にリタイアしており、今後バグ修正などが入ることはありません。そこでdevtoolset-8をインストールしてみましょう。

# yum install devtoolset-8

 これでgcc/c++/gfortran/gdb/make/libstdc++/binutils/ltrace/straceなど、紐づくパッケージが27個も入ります。c++周りだけが必要であれば、devtoolset-8-gcc-c++をインストールするという選択肢もあります。

 インストールは/opt/rh以下にされていて、それ以外の場所を一切汚しません。ユーティリティを使って、こちらに一時的に優先PATHを作るようにして動きます。

SCLのgccを使ってみる

 基本的にsclコマンドやscl_sourceコマンドを用います。インストールされているものを調べてみましょう。

$ scl -l
devtoolset-8

 この中のgccを使うには以下のようにします。

$ scl enable devtoolset-8 'gcc -v'
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/opt/rh/devtoolset-8/root/usr/libexec/gcc/x86_64-redhat-linux/8/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto 
...中略...
Thread model: posix
gcc version 8.3.1 20190311 (Red Hat 8.3.1-3) (GCC) 

 見事gcc-8.3.1が使えるようになりました。このやり方ではdevtoolset-8以下を優先して使うよう環境変数が設定されたシェルを個別に起動してこれを実現しています。しかし、毎回scl enable...を付けて使うわけにはいかないでしょう。そこで現在のシェル上でこの設定を有効にするには以下のようにします。

$ source scl_source enable devtoolset-8
もしくは
$ source /opt/rh/devtoolset-8/enable
$ gcc -v
...中略...
gcc version 8.3.1 20190311 (Redhat 8.3.1-3) (GCC) 

 もし、恒常的にこの状態にするのであれば、.bashrcなどに記述してしまうこともできます。ただし、コレを実行したシェル内で、元に戻すことはできません。コマンド実行で環境を変えた場合はログアウトしてください。.bashrcを書き換えた場合は、当該部分をコメントアウトしておく必要があります。

何が起きているのか

 実行前後で環境変数を見比べれば一目瞭然です。

$ env |grep devtool

まとめ

 普段お使いのOSを大きくいじることなく、最新の環境を手に入れる方法はSCL以外にもいくつかありますが、ユーザーが必要なものを正しく揃えてビルドしてインストールするというのは、手慣れていても結構面倒で、まして管理するとなると不安が残ります。既存環境を上書きする危険もあります。このようにまとまった形でパッケージとして提供されているというのは大変便利です。

 ただし、glibcに関しては入れ替えはできません。異なるバージョンのglibcを求められた場合は、対応するOSの導入や仮想化、そしてSingularityやDockerなどコンテナのご利用を検討ください。また、RHEL/CentOS8系では、こうしたことがそもそも必要ないよう、通常のアップデートで環境の維持と最新環境の両立が実現できるような仕組みが考えられています。