Upgrading GCC/ja

この文書では、GCC のアップグレード手順を案内しています.

はじめに
この記事は、GCCの"アップグレード"についてです. 反対にもしもGCCをダウングレードしたら、望まぬ弊害が起こる危険性があります. また、一般的に報告されている問題のいくつかについては、トラブルシューティングの節を参照してください.

次のセクションでは、GCCのアップグレード（とそれらがいかに簡単か）への迅速なプライマーを提供します. GCCのアップグレードの背後にある長い理由を読みたい場合は、GCC アップグレードの詳説に進んで下さい.

ショートバージョン
GCC をアップグレードしたときには、コンパイラのバージョンを変更することと、libtool を再ビルドすること以外には必要なことはありません：

ただし、GCC を 3.4.0 (3.x 系) や 4.1 より前のバージョンからアップグレードしたときには、 も実行する必要があります：

現在のバージョンを確認し、旧バージョンをアンインストールしましょう:

以上です. 新しいコンパイラで楽しんでください！

はじめに
GCC のアップグレードはいつも謎めかされてきました. というのも、「ほかには何もしなくていいよ」というものから、「システム全体の再ビルドを2度しなければならないよ」というものまで、言われることに幅があるからです. こうした疑念のおおよそは、ABI の互換性にまつわる混乱からきています. しかしまずは、 にまつわることについて軽く指摘しておきます.

libtool と fix_libtool_files.sh
以前は、GCC を Gentoo にインストールした際には という特別なコマンドを実行する必要がありました. 今では、このコマンドの実行はパッケージそのものの展開と一緒に（ toolchain eclassを通じて）自動的に行われるようになりましたから、このコマンド自体を改めて実行する必要はありません.

ではなぜ、 のバージョンをアップグレードした後には libtool を再ビルドする必要があるのでしょうか？　それは、libtool は、プラットフォーム特有のコードを一般化したインターフェイスに集約することで、アプリケーションソフトがプラットフォーム特有の側面を意識することなく共用ライブラリを利用可能にするものだからです. この機能を適切に実現するには、 のスクリプトは、様々な場所にある共用ライブラリを見つけ出して、その中にハードコーディングされた のバージョン情報を得なければなりません.

ABI の変化
ABI、あるいはApplication Binary Interfaceは、コンパイラ、アセンブラ、リンカ、そして言語ランタイムサポート(情報源: GCC Binary Compatibility)を含む、プログラムのバイナリ表現を扱うすべてのツールによって使用される規則の集まりです. バイナリアプリケーションやライブラリに使用されているABIが変更されると、C++のコードを用いているすべてのライブラリをビルドしなおすまで、リンカのエラーやプログラムの誤動作が発生する危険性があります.

そう、C++です、ほとんどの非互換はC++ ABIの中で生じるためです. もしあなたがGCC 4.1やGCC5.1へアップグレードした場合、おそらくABIの問題に直面することになるでしょう. これは、私達が (GCC 3からGCC 4.1へのアップグレードの場合)あるいは (GCC 4からGCC 5.1へのアップグレードの場合)に対してを使う理由でもあります.

では、なぜこれはGCC 3.4.0/4.1/5.1までにおいてのみ必要とされるのでしょうか? それは、それらのバージョン以降、GCCがアプリケーションやライブラリの再ビルドの必要性をなくす前方互換のABIを採用しているからです. もちろん、保証は無期限に与えられるものではありえませんが、非互換が再び生じたら、私たちはそれをここへ確実に文書化します. その場合、おそらくライブラリのバージョンは増加していることでしょう.

C++11 (および C++14) 特有の事象
GCC(より具体的には、libstdc++)は、ABIの安定性を保証するために労を惜しみませんが、この保証はlibstdc++の中のC++のすべての部分に及ぶわけではありません. 公式には、3.4以降のバージョンにおいて、GCC/libstdc++はC++98/C++03 ABIの安定性のみを保証し、それ以上ではありません. このことはC++11に依存するパッケージに関しては重大です. GCCはC++11 ABIの安定性の保証をバージョン5.1以降でのみ提供しています. これは、gccのバージョン(マイナーバージョンであっても)の変更(4.7.3 -> 4.7.4など)はC++11のコードからビルドされたバイナリにABI破壊をもたらす、ということを意味しています.

さらなる情報や実例は、以下を見てください：


 * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61758
 * https://blogs.gentoo.org/blueness/2015/03/10/the-c11-abi-incompatibility-problem-in-gentoo/
 * https://stackoverflow.com/questions/16190269/g-always-backward-compatible-with-older-static-libraries/16196475#16196475
 * https://stackoverflow.com/questions/16190269/g-always-backward-compatible-with-older-static-libraries/16196475#16196475

すべてをリビルドすべきか
「GCC の新たなバージョンを入れたときには、各パッケージのすべてを再ビルドせねばならない」と心に誓っている人もいます. もちろん、そうする意味はありません. なぜなら、ビルドやインストールに GCC を一切使わないアプリケーションソフトもたくさんあり、そうしたソフトウェアには影響がないからです.

そうはいっても、彼らが完全に間違えているかというと、そうでもありません： 新しいバージョンの GCC ではしばしば、プロセッサの命令セットのサポートが向上していることがあります. そうすると、より良い性能が得られるアプリケーションソフトもあるかもしれません. そうした性能の向上は一般的にたかが知れている範囲ですが、ときには（特に CPU に大きく頼っているソフトウェアでは）目立った向上が生み出されることもあります.

また、同じコンパイラを用いてビルドする必要があるパッケージ群についても、既知の例があります. これらのパッケージについては、通常パッケージメンテナが(それらが常に同じバージョンのGCCでビルドされるように)同時にbumpを行いますが、これらのパッケージからの「つまみ食い」的な再インストールは困難であることがわかっています. さまざまなパッケージ群は、この問題の良い例です.

libstdc++.so.6: version `GLIBCXX_3.4.15' not found
アップデートの途中、以下のようなエラーに遭遇することがあります:

これは、依存しているライブラリをビルドしたものよりも古いバージョンのGCCでパッケージをビルドしようとしていることを表しています. C++ ABIは前方互換であると述べたことを思い出しましたか? 確かにそれは事実なのですが、そのことは、アプリケーションのビルドやライブラリのリンクにあたって、(そのライブラリをビルドしたものに比べて)より高い(または同じ)バージョンのGCCが使用できる、ということを保証するに過ぎません.

libstdc++に依存しているすべてのパッケージを再ビルドするには、上のrevdep-rebuildの節を参照してください.

どのパッケージで再ビルドが必要とされているか?
以下の表は、インストールされていれば再ビルドが必要なパッケージとその理由を表したものです.

参考

 * Upgrade GCC up to 4.1 この文書の以前のバージョン
 * Upgrading from gcc-4.x to gcc-5.x
 * Fedoraの'Changes/GCC6' Wikiページ