はじめに
CentOS6 で比較的新しいソフトウェアを実行しようとすると、
/usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by <new software>)
のようなエラーが発生する事があります。これは CentOS6 にインストールされているライブラリが古く、ソフトウェアが要求するバージョンと合わないためです。
今回、libstdc++ ライブラリを例にとって、CentOS6 に新しいバージョンのライブラリをインストールする方法を紹介します。
インストールされている libstdc++ の確認
インストールされている libstdc++ に組み込まれているバージョンを確認します。
$ strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX GLIBCXX_3.4 GLIBCXX_3.4.1 GLIBCXX_3.4.2 GLIBCXX_3.4.3 GLIBCXX_3.4.4 GLIBCXX_3.4.5 GLIBCXX_3.4.6 GLIBCXX_3.4.7 GLIBCXX_3.4.8 GLIBCXX_3.4.9 GLIBCXX_3.4.10 GLIBCXX_3.4.11 GLIBCXX_3.4.12 GLIBCXX_3.4.13 GLIBCXX_FORCE_NEW GLIBCXX_DEBUG_MESSAGE_LENGTH
アプリケーションが要求するバージョン「GLIBCXX_3.4.15」が含まれていないことを確認できます。
gcc のビルド
libstdc++ は gcc に含まれています。gcc をビルドして、libstdc++ を取り出して既存のものと置き換えます。
ビルドに必要なヘッダーのインストール
$ sudo yum install gmp-devel mpfr-devel libmpc-devel
$ sudo yum install glibc-devel.i686
64bit 環境では、glibc-devel.i686 (32bit 版) もインストールしないと、下記のようなエラーが発生しました。
/usr/include/gnu/stubs.h:7:27: fatal error: gnu/stubs-32.h: No such file or directory compilation terminated. make: *** [bitmap.o] Error 1
ソースコードのダウンロード
ミラーサイトからソースコードをダウンロードします。
$ mkdir -p ~/src
$ cd ~/src
$ curl -LO http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-4.8.4/gcc-4.8.4.tar.gz
$ tar fxz gcc-4.8.4.tar.gz
$ cd gcc-4.8.4
CentOS6 にインストールされている libstdc++ のバージョンは 4.4.7 で、ミラーサイトにアップロードされている最新版は 5.1.0 でした。(2015.05.15 現在)今回は「メジャーバージョンが同じで、マイナーバージョンが偶数のもののうち最新のもの」という条件で、4.8.4 を選びました。コンパイルには時間がとてもかかります。
ビルド
$ ./configure
$ make
libstdc++ のビルドが済めば、ビルドのためだけに必要だったパッケージを下記コマンドで削除できます。
$ sudo yum remvoe gmp-devel mpfr-devel libmpc libmpc-devel
$ sudo yum remove glibc-devel.i686 glibc.i686 nss-softokn-freebl.i686
新しいライブラリのインストール
現在のライブラリインストール状況を確認して、目的のライブラリ「libstdc++.so.6.0.19」のみコピーします。
$ ls -l /usr/lib64/libstd*
lrwxrwxrwx. 1 root root 19 5月 13 09:17 2015 libstdc++.so.6 -> libstdc++.so.6.0.13
-rwxr-xr-x. 1 root root 989840 10月 15 07:48 2014 libstdc++.so.6.0.13
$ sudo cp ${HOME}/src/gcc-4.8.4/x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.19 /usr/lib64
既存のライブラリ (libstdc++.so.6.0.13) から、先ほどコピーした新しいライブラリに切り替えます。 古い方のライブラリはシンボリックリンクを含めて削除せず、いつでも切り戻せるよう移動するだけにします。
$ cd /usr/lib64
$ sudo mv libstdc++.so.6 libstdc++.so.6.bak
$ sudo ln -s libstdc++.so.6.0.19 libstdc++.so.6
$ ls -l /usr/lib64/libstd*
lrwxrwxrwx. 1 root root 19 5月 15 11:52 2015 libstdc++.so.6 -> libstdc++.so.6.0.19
-rwxr-xr-x. 1 root root 989840 10月 15 07:48 2014 libstdc++.so.6.0.13
-rwxr-xr-x. 1 root root 6469787 5月 15 11:51 2015 libstdc++.so.6.0.19
lrwxrwxrwx. 1 root root 19 5月 13 09:17 2015 libstdc++.so.6.bak -> libstdc++.so.6.0.13
最後に、目的のバージョンの「GLIBCXX_3.4.15」が有効になっているか確認します。
$ strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBCXX_3.4.14
GLIBCXX_3.4.15
GLIBCXX_3.4.16
GLIBCXX_3.4.17
GLIBCXX_3.4.18
GLIBCXX_3.4.19
GLIBCXX_FORCE_NEW
GLIBCXX_DEBUG_MESSAGE_LENGTH
無事に、バージョン 3.4.15 がリストされました。