GCC のアップグレード

From Gentoo Wiki
Jump to: navigation, search
This page is a translated version of the page Upgrading GCC and the translation is 100% complete.

Other languages:
English • ‎español • ‎日本語 • ‎한국어 • ‎русский • ‎中文(中国大陆)‎

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

クイックスタート

はじめに

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

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

ショートバージョン

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

root #emerge -u sys-devel/gcc
root #gcc-config -l
[1] i686-pc-linux-gnu-4.4.5 *
[2] i686-pc-linux-gnu-4.5.3
root #gcc-config 2
root #env-update && source /etc/profile
root #emerge --ask --oneshot sys-devel/libtool

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

root #revdep-rebuild --library 'libstdc++\.so\.5'

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

root #gcc --version
root #emerge --ask --depclean =sys-devel/gcc-4.4.5

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

GCC アップグレードの詳説

はじめに

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

libtool と fix_libtool_files.sh

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

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

ABI の変化

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

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

root #revdep-rebuild --library 'libstdc\+\+.so.6' -- --exclude gcc

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

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破壊をもたらす、ということを意味しています。

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

すべてをリビルドすべきか

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

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

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

トラブルシューティング

libstdc++.so.6: version `GLIBCXX_3.4.15' not found

アップデートの途中、以下のようなエラーに遭遇することがあります:

CODE GLIBCXX_x.y.z not found
cmake_bootstrap_28021_test: /usr/lib/gcc/i486-pc-linux-gnu/4.1.2/libstdc++.so.6:
version `GLIBCXX_3.4.11' not found

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

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

どのパッケージで再ビルドが必要とされているか?

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

パッケージ 再ビルドが必要な理由 ...
sys-devel/libtool libtoolアプリケーションは、GCCの内部ライブラリへのパスをハードコードしています
sys-devel/llvm 再ビルドしないと、gccの厳密なバージョンによって、LLVMを利用する他のebuild(例えば media-libs/mesa)でリンクエラーに遭遇することがあります

参考