Gentoo GCCアップグレードガイド

Wernfried Haas  Author
Jan Kundr叩t  Author
Mark Loeser  Editor
武田洋之  翻訳
Takeshi Matsuba  翻訳

更新日 2007年 4月 3日
このドキュメントのオリジナルバージョン の更新日は2008年 7月 19日

1.  はじめに

GCCのアップグレード

なぜあなたはアップグレードすべきなのでしょうか? GCCはあなたのシステムの他のパッケージと非常に似ていますが、 ちょっとだけ重要です。 あなたを不愉快にさせるバグが修正されたとき、 あなたが必要とする新しい機能が導入されたとき、 あるいは、あなたがシステムを最新に保ちたいなら、いつでもGCCをアップグレードすべきです。 もし、前述した場合が当てはまらなくても、 あなたが使用しているGCCバージョンがGentoo開発者にサポートされている間は、アップグレードを安全に延期することができます。

もし新しいメジャーバージョンのGCC(3.3.6 から 3.4.5のような)をインストールしても、 システムがそれを使うように自動的には切り替わりません。 移行のためには追加の手順が要求されるため、明示的に変更する必要があります。 もし切り替えないことにしたら、Portageはあなたの気がが変わる、つ まり古いコンパイラをシステムから削除するまでは、古いバージョンの コンパイラを使い続けるでしょう。 メジャーでないGCCのアップグレード (3.4.5 から3.4.6のような)では、自動的に切り替わります。

このガイドは、あなたのGentooシステムで使用されているコンパイラのシームレスなアップグレードに必要な手順を説明しています。 GCC 3.3から3.4へのアップグレードと、 libstdc++の問題という特別なセクションが設けられています。 2つ目の特別なセクションとして、GCCのメジャーまたはマイナーなバージョンがリリースされた後に、 stage3のtarballを使ってGentooを初めてインストールするユーザー向けのセクションを設けました。

警告: GCC 3.4(または3.3)からGCC 4.1またはそれ以上のバージョンへのアップグレードは、下記の一般的なアップグレードの手順が必要です。 なぜなら、GCC 3.4とGCC 4.1は少し異なるABIを使用しているからです。

2.  一般的なアップグレードの手順

はじめに

重要: もしあなたが、GCC-3.3からGCC-3.4へのアップグレードについての手順を探しているなら、 専用のセクションを参照してください。

重要: もしあなたが新しくインストールしたマシンでのGCCのアップグレードについての手順を探しているなら、 専用のセクションを参照してください。

一般的に3.3.5から3.3.6のようなバグ修正リリースへのアップグレードは、完全に安全です。 ただ新しいバージョンをemergeし、あなたのシステムがそれを使うように切り替え、 影響のあるパッケージlibtoolだけを再構築すればよいです。 しかし、GCCアップグレードによってバイナリ互換がなくなる場合もあります。 そのような場合、影響のあるパッケージ(あるいは、toolchainとシステム全体)は再構築される必要があります。

手動で新しいバージョンへコンパイラを切り替える必要性を話しましたとき、 自動ではこれは起こらないといいました。 しかし、例外が1つあります。 3.3.5から3.3.6のようなバグ修正リリースで、1つのシステムにこれらを共存させるために"multislot"を使用していない場合です。 ユーザの大部分は"multislot"によって利益を得られないので、デフォルトでは無効にされています。

コード表示 2.1: GCCのアップグレード

# emerge -uav gcc

("i686-pc-linux-gnu-4.1.1" の部分は、あなたがアップグレードしようとしているGCCバージョンとCHOSTの設定で読み替えてください)
# gcc-config i686-pc-linux-gnu-4.1.1
# env-update && source /etc/profile

もし、gcc 3 から gcc 4へのアップグレード(例えば、この例では 3.4.6 から 4.1.1)を行うなら、fix_libtool_files.shを手動で実行する必要があります。
# fix_libtool_files.sh 3.4.6

(libtoolの再構築)
# emerge --oneshot -av libtool

完全にシステムを安全な状態にするには、 必ずtoolchain、それからworldを再構築し、新しいコンパイラを使用するようにしないといけません。

コード表示 2.2: システムの再構築

# emerge -eav system
# emerge -eav world

ここで古いGCCバージョンを削除するのは安全です。 もし必要だと感じるなら次のコマンドを実行してください(通常は、 =sys-devel/gcc-3.4*の部分をあなたが削除したいバージョンに読み替えてください)

コード表示 2.3: 古いバージョンのGCCを削除

# emerge -aC =sys-devel/gcc-3.4*

重要: GCC 4.1以降では2.4.34より新しいカーネルしかコンパイルできないことに注意してください。 古いカーネルを使用したいなら、古いバージョンのGCCを削除しないでください。

重要: GCC-3.3からアップグレードしている場合、古いC++バイナリアプリケーションの適切な機能を確実にするため、 emerge --oneshot sys-libs/libstdc++-v3を実行すべきです。

3.  GCC-3.3から3.4へのアップグレード

はじめに

2つのバージョン間でC++ ABIが変更されたため、 GCC/3.3から3.4へのアップグレードは、それほどシームレスではありません。 このためlibstdc++ライブラリで問題があり、これを処理をする必要があります。

選択肢

重要: もしGCC 3.4からGCC 4.1へアップグレードする場合は、一般的なアップグレードの手順を参照してください。

重要: もしあなたがSPARCマシンをアップグレードする場合、GCCのパラメータのやり取りで内部的にABIが変更されたため、完全なシステムのリビルドを行う必要があります。

もしGCC 3.3からGCC3.4へのアップグレードを行う場合、システムをアップグレードするには2つの方法があります。 最初の方法の方が手早くでき、 gentoolkitパッケージに含まれるrevdep-rebuildツールを使う必要があります。 これに対し、2番目の方法は、 システム全体をスクラッチから再構築し、GCCの新しい機能を使うことができます。 これらの2つの方法からどちらを選ぶかはあなた次第です。 ほとんどの場合、最初の方法で十分です。

GCC 3.3からGCC4.1へアップグレードする場合は、revdep-rebuildを基にした方法は使用せず、完全にシステムを再構築してください。

revdep-rebuildを使う

この方法では、まだインストールしていないなら、 まず最初にgentoolkitをインストールする必要があります。 そしてGCCをアップグレードし新しいコンパイラに切り替えます。 また、toolchainを確実に健全な状態にするためにlibtoolパッケージを再構築します。

コード表示 3.1: gentoolkitのインストールとGCCのアップグレード

# emerge -an gentoolkit
# emerge -uav gcc
("i686-pc-linux-gnu-3.4.5"の部分は、
あなたがアップグレードしようとしているGCCバージョンとCHOSTの設定で読み替えてください)
# gcc-config i686-pc-linux-gnu-3.4.5
# source /etc/profile

(libtoolの再構築)
# emerge --oneshot -av libtool

ここでrevdep-rebuildに実際に再構築するパッケージを問い合わせます。 その後、revdep-rebuildに実際にパッケージを再構築するよう指示します。 これにはしばらく時間がかかりますが辛抱してください。

コード表示 3.2: revdep-rebuildを使う

# revdep-rebuild --library libstdc++.so.5 -- -p -v
# revdep-rebuild --library libstdc++.so.5

注意: 古くなっている、または、マスクされているために、 存在しないパッケージバージョンで問題が起きる可能性があります。 こうした事態に遭遇したら、revdep-rebuildに対して--package-namesオプションを使ってください。 こうすることで、厳密な名前とバージョンではなくパッケージ名に基づいて再構築するようになります。

古いC++アプリケーションやrevdep-rebuildが検出できなかったパッケージにバイナリ互換を提供するために、 GCC 3.3をシステムからunmergeする前にsys-libs/libstdc++-v3をマージする必要があります。

コード表示 3.3: libstdc++-v3のインストールと古いGCCの削除

# emerge --oneshot sys-libs/libstdc++-v3
# emerge -aC =sys-devel/gcc-3.3*

emerge -eを使う

この方法は、より時間がかかる方法で、 新しいコンパイラでシステム全体を再構築され、それゆえに、より安全です。 まずGCCとlibtoolをアップグレードし、新しいコンパイラに切り替えます。

コード表示 3.4: GCCのアップグレード

# emerge -uav gcc
("i686-pc-linux-gnu-3.4.5"の部分は、
あなたがアップグレードしようとしているGCCバージョンとCHOSTの設定で読み替えてください)
# gcc-config i686-pc-linux-gnu-3.4.5
# source /etc/profile

もし、gcc 3 から gcc 4へのアップグレード(例えば、この例では 3.3.6 から 4.1.1)を行うなら、fix_libtool_files.shを手動で実行する必要があります。
# fix_libtool_files.sh 3.3.6


(libtoolを再構築)
# emerge --oneshot -av libtool

古いC++アプリケーションにバイナリ互換を提供するために、 sys-libs/libstdc++-v3をあなたのシステムにインストールする必要があります。

コード表示 3.5: libstdc++-v3のインストール

# emerge --oneshot sys-libs/libstdc++-v3

ここでsystemターゲットに対して最初の再構築を実施し、次にworldターゲットを実施します。 toolchain全体とシステムをサポートするファイル全体を再構築するので、 これには、あなたのインストールしているパッケージの数に応じてとても長い時間がかかります。 これはtoolchain自身を含む全てのパッケージが新しいtoolchainで確実に再構築されるのに必要です。

コード表示 3.6: systemとworldを再構築する

# emerge -e system
# emerge -e world

この時点で古いバージョンのGCCを削除しても安全です。

コード表示 3.7: 古いGCCの削除

# emerge -aC =sys-devel/gcc-3.3*

4.  初めてインストールしたマシンでのGCCのアップグレード

はじめに

stage3のtarballを使ってシステムをインストールした後に、GCCのアップグレードを行うのは簡単な事です。 新しくインストールしたユーザーが有利な点は、古いGCCに依存したソフトウェアが過剰にインストールされていない事です。 下記の例は、GCC 3.3からGCC 3.4へのアップグレードです。 他のバージョンのGCCからアップグレードする場合は、一部異なる部分があるでしょう。 例えば、以下でrevdep-rebuildで使用されるライブラリはGCC 3.3に特化していますが、 同じようにlibstdc++-v3をインストールする必要があります。

もしユーザーが、まだシステムにカスタマイズを加えていなければ、 GCCの新しいバージョンにアップグレードするのは、わずかな手順しかありません。 GCC 3.3から3.4へのアップグレードでは、二つの選択肢があります。 しかし、GCC 3.3から3.4へのアップグレードでない場合は、二つの方法にほとんど違いが無いため、とても簡単です。 最初の方法は早くてgentoolkitにあるrevdep-rebuildツールを利用する、上述の手順に似ています。 revdep-rebuildを使う事により、実際にGCCライブラリに依存しているパッケージのみリビルドされます。 一方2番目の方法は新たにインストールしたパッケージが新しいGCCにより再コンパイルされるため、時間がかかります。 2番目の方法は、決して必要ではありませんが、完全なアップグレードを提供するためだけに、記述されています。

最初の手順は、二つの方法で共通な手順で、みんなが完了すべきです。

コード表示 4.1: GCCのアップグレード

# emerge -uav gcc
("i686-pc-linux-gnu-3.4.5"の部分は、
あなたがアップグレードしようとしているGCCバージョンとCHOSTの設定で読み替えてください)
# gcc-config i686-pc-linux-gnu-3.4.5
# source /etc/profile

(libtoolのリビルド)
# emerge --oneshot -av libtool

古いバイナリのC++アプリケーションに互換性を提供するため、 sys-libs/libstdc++-v3 をシステムにマージする必要があります。

コード表示 4.2: libstdc++-v3のインストール

# emerge --oneshot sys-libs/libstdc++-v3

revdep-rebuildの使用

この方法では、まだgentoolkitをインストールしていないなら、 まず最初にインストールする必要があります。 リビルドすべきインストールされたパッケージを実際に検索するためにrevdep-rebuildを実行し、 それらをリビルドします。

コード表示 4.3: gentoolkitをインストールし、revdep-rebuildを実行する

# emerge -an gentoolkit
# revdep-rebuild --library libstdc++.so.5 -- -p -v
# revdep-rebuild --library libstdc++.so.5

注意: 古かったりmaskされていたりする理由でパッケージのバージョンが存在しない問題が発生する可能性があります。 この場合、revdep-rebuild--package-namesオプションを使うのが良いでしょう。 これにより、正確な名前とバージョンではなくパッケージ名に基づいて、パッケージの再コンパイルが行われます。

emerge -eを使う

この方法は、新しいコンパイラでシステムの全てを確実にリビルドするため、大変遅いです。 これは必要ないのですが、もしあなたがシステムのコンパイルに影響を与えるCFLAGSやmake.confの値の変更を行っていれば、有効です。

最初のインストールの後にこれらを実行しているので、既にインストールされたシステム上でアップグレードをしているときに、 worldを再コンパイルする必要はありません。 しかし、全てのパッケージを確実にアップデートするために、worldをsystemの代わりにアップデートする選択もできます。

コード表示 4.4: systemのリビルド

# emerge -e system

後始末

この時点で古いバージョンのGCCを削除しても安全です。 YOUR-NEW-GCC-VERSIONの部分は実際にアップグレードしたバージョンに置き換えてください。

コード表示 4.5: 後始末

# emerge -aC "<sys-devel/gcc-YOUR-NEW-GCC-VERSION"

5.  共通的な落とし穴

アップグレード中はdistccを無効にすることが重要です。 あなたのノードで複数のコンパイラバージョンを使うことはビルドで問題を起こすでしょう。 cacheオブジェクトはとにかく無効になるため、ccacheに対しては何かをする必要はありません。

カーネルとカーネルモジュールに対しては、常に同じGCCバージョンを使用してください。 いったんworldを新しいGCCで再構築したら、 app-emulation/qemu-softmmuのような外部モジュールは、ロードに失敗します。 これを修正するには、カーネルを新しいGCCで再構築してください。

もしSPARCマシンでアップデートを行う場合は、worldを再構築した後にsilo -fを確実に再実行して、 起こりそうな問題を回避しましょう。

よくあるエラーメッセージ

もしあなたのシステムがlibtool: link: `/usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.6/libstdc++.la' is not a valid libtool archiveと言うようなエラーを出すなら、 /sbin/fix_libtool_files.sh 3.3.6を実行してください。 ("3.3.6"の部分はエラーメッセージで出力されるバージョン番号で読み替えてください)。

error: /usr/bin/gcc-config: line 632: /etc/env.d/gcc/i686-pc-linux-gnu-3.3.5: No such file or directoryと言うエラーが出る場合、 /etc/env.d/gcc/config-i686-pc-linux-gnuを削除し、 gcc-configを再度実行し、続けてsource /etc/profileとしてみてください。 cross-compilerをセットアップしていない場合は、単にこれを実行してください。

emerge -e system または emerge -e worldの実行中にパッケージの構築に失敗した場合、 emerge --resumeで再開することができます。 もしパッケージの構築に再度失敗するようなら、emerge --resume --skipfirstとすることでそのパッケージをスキップできます。 この間に他のemergeを実行しないでください。 さもなければ再開情報が失われてしまいます。

コンパイラのアップグレード中にspec failure: unrecognized spec optionというエラーが出た場合、 デフォルトコンパイラに切り替えて、GCC_SPECS環境変数を削除し、 GCCを再びアップグレードしてください

コード表示 5.1: 1番目のspecsを修復

# gcc-config 1
# source /etc/profile
# unset GCC_SPECS
# emerge -uav gcc