GCC のアップグレード

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

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

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

Please note that downgrading GCC might have unwanted side effects. Refer to the troubleshooting section for some commonly reported issues.

ショートバージョン

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

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

root #emerge --ask --oneshot sys-devel/gcc
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
Note
If you are upgrading from gcc 4.x to gcc 5.x or later, additional instructions apply; please see then the separate page Upgrading from gcc-4.x to gcc-5.x.

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

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

After that, verify system integrity running revdep-rebuild:

root #revdep-rebuild

Enjoy the new compiler!

GCC アップグレードの詳説

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

libtool と fix_libtool_files.sh

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

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

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

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

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

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

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

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

Apart from such "benign" benefits, rebuilding everything from scratch may be necessary in some cases to fix problems that don't seem to have any obvious cause.

Some software problems are inherently difficult to diagnose and yet could be solved by simply rebuilding one or more appropriate packages. If such a problem has arisen following a GCC upgrade and persists after using the revdep-rebuild approach described above (and after rebuilding any other obviously relevant packages), a complete system rebuild may be the answer.

The "safest" (but also most time-consuming) way to accomplish this is to use the --emptytree (-e) option of emerge to rebuild the system set and then the world set:

root #emerge --ask --emptytree --usepkg=n @system
root #emerge --ask --emptytree --usepkg=n @world

Users are urged to try this approach before reporting any bugs that might have been caused by a GCC upgrade.

(Note that the commands above will cause the packages in the "system" set to be rebuilt twice, which is necessary to be absolutely certain that every package gets built in the same [presumably] "problem-free" environment. Any problems that remain after doing this are due to either "genuine bugs" that should be reported or poor system configuration.)

トラブルシューティング

rebuild of boost

If dev-libs/boost needs to be rebuilt, one will get the following error message:

root #emerge ...
 
checking for the Boost _____ library... no
configure: error: cannot find the flags to link with Boost _____

One can rebuild with:

root #emerge --ask --oneshot --usepkg=n --verbose dev-libs/boost

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の節を参照してください。

参考

References