Red Hat Training

A Red Hat training course is available for Red Hat Enterprise Linux

第4章 コンパイルおよびビルド

Red Hat Enterprise Linux 6 には、ソースコードのコンパイルおよびビルド用のツールなど、ソフトウェア開発に使用する多くのパッケージが含まれています。本章では、ソースコードのコンパイルに使用するパッケージおよびツールのいくつかを説明します。

4.1. GNU コンパイラーコレクション (GCC)

GNU コンパイラーコレクション (GCC) は、様々なプログラミング言語 (C、C++、ObjectiveC、ObjectiveC++、Fortran、Ada を含む) を非常に最適化されたマシンコードにコンパイルするツールセットです。これらのツールには、様々なコンパイラー (gccg++ など)、ランタイムライブラリー (libgcclibstdc++libgfortranlibgomp など)、その他のユーティリティーが含まれます。

4.1.1. GCC ステータスおよび機能

Red Hat Enterprise Linux 6 用の GCC は 4.4.x リリースシリーズをベースとしており、予定されているリリースからのバックポート (GCC 4.5 を含む)、バグ修正や機能強化が含まれていますが、Red Hat Enterprise Linux 6 の機能が凍結された際に、GCC 4.5 の成熟度はエンタープライズディストリビューションには不十分とみなされました。
この標準化は、4.4 シリーズの更新が利用可能になると (4.4.1、4.4.2 など)、Red Hat Enterprise Linux 6 に含まれているコンパイラーに更新として取り込まれることを意味します。Red Hat は 4.4 シリーズ以外の予定されているリリースから新たなバックポートや機能強化をインポートする可能性がありますが、Enterprise Linux リリース内での互換性を断つものではありません。場合によっては、標準に準拠していないコードがコンパイルに失敗することや、バグ修正や標準準拠のプロセス中に機能が変更することあります。
前回の Red Hat Enterprise Linux リリース以降、GCC は 4.2.x、4.3.x、4.4.x の 3 つのメジャーリリースを行いました。以下は、変更点の概要になります。
  • inliner、実行されないコードの除外ルーチン、コンパイル時間、メモリ使用コードが改善されました。このリリースでは、新たなレジスタアロケータ、指示スケジューラ、ソフトウェアパイプラインの機能があります。
  • OpenMP のバージョン 3.0 仕様が C、C++、Fortran コンパイラー対応となっています。
  • 予定されている ISO C++ 標準 (C++0x) の体験サポートが含まれています。これには、自動/inline ネームスペース、文字タイプ、スコープ列挙のサポートがあります。これを有効にするには、コンパイラーオプションの -std=c++0x (GNU 拡張機能を無効化) か -std=gnu++0x を使用します。
    C++0x の改善点の詳細リストについては、以下のリンク先を参照してください。
  • GCC は Variable Tracking at Assignments (VTA) インフラストラクチャーを組み込むようになりました。これにより、最適化中の GCC の変数追跡機能が向上され、GNU Project Debugger や SystemTap、その他のツール用に作成されるデバッグ情報 (つまり、DWARF) が改善されます。VTA の概要については「Variable Tracking at Assignments」を参照してください。
    VTA を使うと、以前の GCC リリースと比べてはるかに最適化されたコードのデバッグがうまく実行でき、優れたデバッグ体験を提供するために -O0 でコンパイルする必要がなくなります。
  • Fortran 2003 のサポートが延長され、Fortran 2008 がサポート対象となりました。
GCC の改善点の詳細なリストは、以下を参照してください。
GCC 4.4 再ベースで導入された変更点に加え、Red Hat Enterprise Linux 6 バージョンの GCC はアップストリームソース (バージョン 4.5 およびそれ以降) からバックポートされた修正および機能強化も備えています。これらの改善点には以下のものが含まれます。
  • 最適化された C++ コードのデバッグ用の DWARF3 デバッグの改善
  • Fortran 最適化の改善
  • ix86、Intel 64 および AMD64、s390 の指示の長さ情報の精度改善
  • Intel Atom のサポート
  • POWER7 のサポート
  • C++ raw 文字列サポート、u/U/u8 文字列リテラルサポート

4.1.2. 言語の互換性

GNU C、C++、Fortran、Java Compiler が指定する アプリケーションバイナリーインターフェース (ABI) には、以下が含まれます。
  • 呼び出し規約。これは、引数の関数への渡され方と関数からの結果の返し方を指定します。
  • レジスタ使用量規約。これはプロセッサーレジスタの割り当ておよび使用方法を指定します。
  • オブジェクトファイル形式。これは、バイナリーオブジェクトコードの表示方法を指定します。
  • サイズ、レイアウト、データ配置のタイプ。これは、メモリでのデータの配置方法を指定します。
  • ランタイム環境が提供するインターフェース。記録されたセマンティクスがあるバージョンから別のバージョンで変更されない部分では、これらは利用可能である必要があり、常に同じ名前を使う必要があります。
Red Hat Enterprise Linux 6 に含まれているデフォルトのシステム C コンパイラーは、C99 ABI 標準と幅広い互換性があります。GCC 4.4 の C99 標準との偏差は、online で追跡されます。
C ABI に加えて、GNU C++ コンパイラーのアプリケーションバイナリーインターフェースは、C++ 言語のサポートに必要な以下のバイナリーインターフェースを指定します。
  • 名前のマングル化およびデマングル化
  • 例外の生成および伝達
  • ランタイムタイプ情報のフォーマット
  • コンストラクターおよびデストラクター
  • クラスおよび派生クラスのレイアウト、配置、パディング
  • 仮想テーブルのレイアウトおよび配置といった仮想機能実装の詳細
Red Hat Enterprise Linux 6 に含まれるデフォルトのシステム C++ コンパイラーは、Itanium C++ ABI (1.86) が定義する C++ ABI に準拠します。
GCC の各バージョンは以前のリリースと互換性を保つようにできる限りの努力がなされていますが、いくつかの非互換性が存在します。
Red Hat Enterprise Linux 6 と Red Hat Enterprise Linux 5 の間における ABI の非互換性

以下は、Red Hat Enterprise Linux 6 と 5 のツールチェーン間での既知の非互換性です。

  • 柔軟性のある配列メンバーの構造体を値でパス/返却すると、Intel 64 および AMD64 で変更する場合がある。
  • long double メンバーのユニオンを値でパス/返却すると、Intel 64 および AMD64 で変更する場合がある。
  • 複雑な浮動メンバーの構造体を値でパス/返却すると、Intel 64 および AMD64 で変更する場合がある。
  • -mavx を使用する場合、x86、Intel 64、AMD64 のプラットフォームでの 256 ビットのベクターのパスが変更される。
  • _Decimal{32,64,128} タイプおよびいくつかのターゲットで値ごとのものを含む総計のパスに複数の変更がある。
  • パックされた char ビットフィールドの圧縮が変更されるケースがある。
Red Hat Enterprise Linux 5 と Red Hat Enterprise Linux 4 の間における ABI の非互換性

以下は、Red Hat Enterprise Linux 5 と 4 のツールチェーン間での既知の非互換性です。

  • C++ ABI が指定するライブラリーインターフェースで、機能スコープの静的変数のスレッドセーフな初期化に変更があります。
  • Intel 64 および AMD64 では、データセグメントが 4GB を超えるアプリケーション構築用の中型モデルは、当時の最新 ABI ドラフトに一致するように再設計されました。ABI の変更が中型モデルのオブジェクト間での非互換性につながっています。
コンパイラーのフラグ -Wabi は、これらの構造文がソースコードのどこに現れるかを示す診断を得るために使用できますが、すべてのケースを捕捉するわけではありません。このフラグは、ベンダー中立の C++ ABI と互換性がないと分かっているコードをコンパイラー生成する際はいつでも警告するので、C++ コードでは特に便利です。
上記に一覧表示した非互換性を除くと、GCC C と C++ 言語 ABI は ほとんど ABI と互換性があります。ほとんどのソースコードは既知の問題に遭遇することはなく、互換性があると考えて問題ありません。
ABI の互換性がある場合には、ソースコードのコンパイルで作成されたオブジェクトを他のシステムに移動できるようになります。特に Red Hat Enterprise Linux では、これで上位 互換性が可能になります。上位互換性とは、特定の Red Hat Enterprise Linux リリースのコンパイラーのバージョンで作成した共有ライブラリーおよびオブジェクトを問題なくリンクできる機能のことです。これには、以降の Red Hat Enterprise Linux でコンパイルされた新たなオブジェクトも含まれます。
C ABI は少なくとも Red Hat Enterprise Linux 3 以降 (上記リストで説明した非互換性を除く)、安定性があると考えられています。Red Hat Enterprise Linux 3 およびそれ以降で構築されたライブラリーは、それ以降の環境 (Red Hat Enterprise Linux 4、Red Hat Enterprise Linux 5、Red Hat Enterprise Linux 6) で作成されたオブジェクトにリンクさせることができます。
C++ ABI は安定性があるものの、C ABI ほどの安定性はありません。また Red Hat Enterprise Linux 4 以降でのみ安定しています (GCC バージョン 3.4 およびそれ以上に対応)。C の場合と同様に、上位互換性のみになります。Red Hat Enterprise Linux 4 およびそれ以降で構築されたライブラリーは、それ以降の環境 (Red Hat Enterprise Linux 5 および Red Hat Enterprise Linux 6) で作成されたオブジェクトにリンクさせることができます。
Red Hat Enterprise Linux 4 より前の Red Hat Enterprise Linux の C++ ABI と互換性のあるコードを強制的に GCC に生成させるため、開発者によっては -fabi-version=1 オプションを使用していました。この方法は、推奨されません。この方法で作成されるオブジェクトは、最新の安定的な ABI に適合するオブジェクトと区別がつかず、異なる ABI の間で (誤って) リンクされる可能性があります。特に、新しいコンパイラーを使ってコードを作成し、これを Red Hat Enterprise Linux 4 より前のツールで構築された古いライブラリーにリンクする場合などです。

警告

特に、コアライブラリー外で複数の依存関係によりカスタムライブラリを開発する場合など、上記の非互換性が原因でリリース間の ABI 共有ライブラリーを適切に維持することは非常に困難になります。このため、共有ライブラリーを開発する際は、Red Hat Enterprise Linux の各リリースで新たなバージョンを構築することを 強く 推奨します。

4.1.3. オブジェクトの互換性と相互運用性

2 つの重要なアイテムは、コンパイラーが使用する基礎的ツールにおける変更と強化、またある言語のコンパイラーの異なるバージョン間での互換性です。
ld (binutils パッケージの一部として配布) や動的ローダー (glibc パッケージの一部として配布される ld.so) などのツールの変更や新機能は、コンパイラーが作成するオブジェクトファイルをわずかに変更する可能性があります。これらの変更では、Red Hat Enterprise Linux の以前のリリースから最新リリースに移動するオブジェクトファイルは機能を失い、ランタイムで異なる動作をし、相互運用性が減少する可能性があることになります。既知の問題分野は以下のとおりです。
  • ld --build-id
    Red Hat Enterprise Linux 6 では、これはデフォルトで ld に渡されます。一方、Red Hat Enterprise Linux 5 では、ld は認識されません。
  • as .cfi_sections サポート
    Red Hat Enterprise Linux 6 では、このディレクティブにより、.cfi* ディレクティブから .debug_frame.eh_frame、または両方を省略できるようになります。Red Hat Enterprise Linux 5 で省略可能なのは、.eh_frame のみです。
  • asldld.sogdbSTB_GNU_UNIQUE%gnu_unique_symbol サポート
    Red Hat Enterprise Linux 6 では、より多くのデバッグ情報が生成されてオブジェクトファイルに保存されます。この情報は、DWARF 標準で詳述されている新機能と標準化されていない新たな拡張機能にも依存しています。Red Hat Enterprise Linux 5 では、asldgdbobjdumpreadelf といったツールはこの新情報に対応できていない可能性があり、新規ツールが作成したオブジェクトとの相互運用に失敗する可能性があります。また、Red Hat Enterprise Linux 5 で作成されたオブジェクトファイルは、これらの新機能に対応していません。これらのオブジェクトファイルは Red Hat Enterprise Linux 6 ツールでは最適でない方法で処理される可能性があります。
    このようにデバッグの強化情報が増えたことで、システムライブラリーと共に出荷される debuginfo パッケージがインストールされていれば、システムライブラリーへの有益なソースレベルでのデバッグが可能になります。debuginfo パッケージに関する詳細情報は、「Debuginfo パッケージのインストール」を参照してください。
上記記載のようなオブジェクトファイルの変更は、prelink のポータブルな使用を妨げる可能性があります。

4.1.4. 後方互換性パッケージ

Red Hat Enterprise Linux の古いバージョンから最新リリースにソースコードや実行可能ファイルを移動するためのパッケージがいくつか提供されています。これらのパッケージは、ソースを動作が変更された新しいコンパイラーに移動する一時的な手助けとして、もしくはコンパイル環境からシステム環境の違いを切り離す便利な方法として使用するためのものです。

注記

Red Hat は、これらのパッケージを今後のRed Hat Enterprise Linux リリースからは削除する可能性があることに留意してください。
以下のパッケージは、Red Hat Enterprise Linux 4 で古いコンパイラーを使用しているかのように Red Hat Enterprise Linux 6 上で Fortran または C++ ソースコードをコンパイルするための互換性ツールを提供します。
  • compat-gcc-34
  • compat-gcc-34-c++
  • compat-gcc-34-g77
以下のパッケージは、Red Hat Enterprise Linux 5 でコンパイルされた Fortran 実行可能ファイルの互換性ランタイムライブラリーを提供し、Red Hat Enterprise Linux 6 の最新リリースで再コンパイルなしで実行できるようにします。
  • compat-libgfortran-41
後方互換性ライブラリーパッケージは、サポートされているシステムライブラリーすべてに提供されているわけではありません。コンパイラーおよび C/C++ 標準ライブラリーに関連するシステムライブラリーのみになります。
後方互換性ライブラリーパッケージに関する詳細は、Red Hat Enterprise Linux 6 『移行計画ガイド』 の 『アプリケーションの互換性』 のセクションを参照してください。

4.1.5. Red Hat Enterprise Linux 5 での Red Hat Enterprise Linux 6 コンパイラー機能のプレビュー

Red Hat Enterprise Linux 5 では、更新としてパッケージ gcc44 が含まれています。これは、Red Hat Enterprise Linux 6 コンパイラーのバックポートで、Red Hat Enterprise Linux 5 を実行するユーザーが Red Hat Enterprise Linux 6 コンパイラーでコードをコンパイルして新機能や最適化を体験してから、次のメジャーリリースの際にシステムをアップグレードすることができます。作成されたバイナリーーは Red Hat Enterprise Linux 6 と前方互換があるため、Red Hat Enterprise Linux 5 上で gcc44 を使用してコンパイルして、Red Hat Enterprise Linux 5、Red Hat Enterprise Linux 6 以降で実行するkとおができます。
Red Hat Enterprise Linux 5 gcc44 コンパイラーは、Red Hat Enterprise Linux 6 と同梱の GCC 4.4.x と適度に調和され、移行を容易にします。ただし、最新機能を使用するには、開発に Red Hat Enterprise Linux 6 を使用することが推奨されます。gcc44 は変換プロセスの支援としてのみ提供されています。

4.1.6. GCC の実行

GCC ツールを使ってコンパイルするには、まず binutilsgcc をインストールします。こられでいくつかの依存関係もインストールされます。
簡単に言うと、ツールは gcc コマンドで動作します。これがコンパイラーの主要なドライバーです。コマンドラインから、ソースファイルの前処理またはコンパイル、オブジェクトファイルおよびライブラリーのリンク、またはこれらの組み合わせを実行できます。デフォルトでは、gcc が提供されている libgcc ライブラリー内の詳細とリンクの処理をします。
GCC が提供するコンパイラー機能は、CDT の一部として Eclipse IDE にも統合されます。これにより多くの利点がもたらされます。グラフィカルインターフェースと完全統合型の環境を好む開発者の場合は特にそうです。
逆に、コマンドラインインターフェースから GCC ツールを使うと、消費するシステムリリースが少なくすみます。これだと、コンパイラーに対する粒度の細かい管理が可能になります。GCC のコマンドラインツールは、グラフィカルモード (ランレベル 5) 外でも使用できます。

4.1.6.1. シンプルな C の使用

GCC を使用した C 言語プログラムの基本的なコンパイルは簡単なものです。次のシンプルなプログラムで開始します。
hello.c

#include <stdio.h>

int main ()
{
  printf ("Hello world!\n");
  return 0;
}

以下の手順は、最も基本的な形での C のコンパイルプロセスになります。

手順4.1 'Hello World' C プログラムのコンパイル

  1. 次のコマンドを使用して hello.c を実行可能ファイルにコンパイルします。
    gcc hello.c -o hello
    作成されるバイナリー hellohello.c と同じディレクトリーにあることを確認します。
  2. hello バイナリー、つまり hello を実行します。

4.1.6.2. シンプルな C++ の使用

GCC を使用した C++ 言語プログラムの基本的なコンパイルは同様のものです。次のシンプルなプログラムで開始します。
hello.cc

#include <iostream>

using namespace std;

int main(void)
{
  cout << "Hello World!" << endl;
  return 0;
}

以下の手順は、最も基本的な形での C++ のコンパイルプロセスになります。

手順4.2 'Hello World' C++ プログラムのコンパイル

  1. 次のコマンドを使用して hello.cc を実行可能ファイルにコンパイルします。
    g++ hello.cc -o hello
    生成されるバイナリー hellohello.cc と同じディレクトリーにあることを確認します。
  2. hello バイナリー、つまり hello を実行します。

4.1.6.3. シンプルなマルチファイルの使用

マルチファイルもしくはオブジェクトファイルの基本的なコンパイルを行うには、以下の 2 つのソースファイルで開始します。
one.c

#include <stdio.h>
void hello()
{
  printf("Hello world!\n");
}

two.c

extern void hello();

int main()
{
  hello();
  return 0;
}

以下の手順は、最も基本的な形式でシンプルなマルチファイルのコンパイルプロセスを説明しています。

手順4.3 マルチソースファイルによるプログラムのコンパイル

  1. 次のコマンドを使用して one.c を実行可能ファイルにコンパイルします。
    gcc -c one.c -o one.o
    生成されるバイナリー one.oone.c と同じディレクトリーにあることを確認します。
  2. 次のコマンドを使用して two.c を実行可能ファイルにコンパイルします。
    gcc -c two.c -o two.o
    生成されるバイナリー two.otwo.c と同じディレクトリーにあることを確認します。
  3. 次のコマンドを使用して one.o および two.o を単一の実行可能ファイルにコンパイルします。
    gcc one.o two.o -o hello
    生成されるバイナリー helloone.o および two.o と同じディレクトリーにあることを確認します。
  4. hello バイナリー、つまり hello を実行します。

4.1.6.4. 推奨される最適化オプション

プロジェクトによって必要な最適化オプションは異なります。最適化では万能型のアプローチはありませんが、以下に留意すべきガイドラインを挙げます。
指示の選択およびチューニング

指示のスケジューリングに正しいアーキテクチャーを選択することは、非常に重要です。デフォルトでは、GCC はほとんどの一般的なプロセッサーに最適化されたコードを作成しますが、コードが動作する CPU が分かっている場合は、それに対応する指示スケジューリングを最適化する -mtune= オプションと、指示選択を最適化する -march= オプションを使用すべきです。

オプション -mtune= は、指示スケジューリングを最適化して、ABI および利用可能な指示セットを除きすべてをチューニングすることでアーキテクチャーに適合させます。このオプションは特定の指示を選択しませんが、その代わりにプログラムのチューニングを行い、特定のアーキテクチャー上での実行を最適化します。たとえば、大体において Intel Core2 CPU を使うのであれば、-mtune=core2 を選択します。選択が間違っている場合は、プログラムは実行しますが、そのアーキテクチャー上での最善の動作にはなりません。そのプログラムが実行する可能性の最も高いアーキテクチャーを常に選択するようにします。
オプション -march= は、指示選択を最適化します。間違った選択をするとプログラムが失敗するので、正確な選択が重要になります。このオプションは、コード生成時に使用される指示セットを選択します。たとえば、プログラムが AMD K8 コアベースの CPU で実行されるのであれば、-march=k8 を選択します。このオプションでアーキテクチャーを指定することで、-mtune= が暗示されます。
-mtune=-march= コマンドは、異なるコード生成 (クロスコンパイル) のためではなく、あるアーキテクチャー内でのチューニングと指示選択のみに使用するようにします。たとえば、Intel 64 や AMD64 プラットフォームからの PowerPC コード生成には使用しません。
-march= および -mtune= の両方で利用可能なオプションの完全一覧については、GCC 4.4.4 Manual: Hardware Models and Configurations のリンクから取得可能な GCC ドキュメントを参照してください。
一般目的の最適化フラグ

コンパイラーフラグ -O2 は、高速コード生成のすぐれた穏健なオプションです。作成されるコードサイズが大き過ぎない場合に、最適化されたコードが作成されます。最善のものがわからない場合は、このオプションを使用してください。

コードサイズが問題とならない場合は、-O3 が推奨されます。このオプションはやや大きめのコードを作成しますが、関数のインラインの頻度が高いため、実行速度が速くなります。浮動小数点集約型コードではこれが理想的なものになります。
他の一般目的の最適化フラグは、-Os です。このフラグはサイズの最適化も行い、より小さいフットプリントがコードのローカリティを増やし、キャッシュミスを減らすような状況で高速コードを作成します。
オブジェクトのコンパイル時には -frecord-gcc-switches を使用します。これにより、オブジェクトをオブジェクト自体にビルドする際に使用されるオプションが記録されます。オブジェクトがビルドされた後で、そのビルドに使用されたオプションセットを見つけ出します。このオプションセットはその後、オブジェクト内の .GCC.command.line と呼ばれるセクションに記録され、以下のように確認可能になります。
$ gcc -frecord-gcc-switches -O3 -Wall hello.c -o hello
$ readelf --string-dump=.GCC.command.line hello

String dump of section '.GCC.command.line':
  [     0]  hello.c
  [     8]  -mtune=generic
  [    17]  -O3
  [    1b]  -Wall
  [    21]  -frecord-gcc-switches
典型的なデータセットを使用して、さまざまなオプションをテストして試すことは非常に重要です。異なるモジュールやオブジェクトを異なる最適化フラグでコンパイルすると、最適な結果が得られる場合がしばしばあります。さらなる最適化チューニングについては、「プロファイルフィードバックを使用した最適化ヒューリスティックのチューニング」 を参照してください。

4.1.6.5. プロファイルフィードバックを使用した最適化ヒューリスティックのチューニング

典型的なソースコードを実行可能ファイルに変換する間、コードの一部と別の部分での速度の重要性やコード速度に対するコードサイズについてなど、数万もの選択をする必要があります。デフォルトでは、これらの選択はコンパイラーが妥当なヒューリスティックを使用して行い、最適なランタイムパフォーマンスを生み出すために長期的にチューニングされます。しかしGCC には、特定の本番環境において特定のマシンで実行可能ファイルを最適化するようにコンパイラーに教える方法があります。この機能は、プロファイルフィードバックと呼ばれます。
プロファイルフィードバックは、以下のような最適化をチューニングするために使用されます。
  • インライン
  • 分岐予測
  • 指示のスケジューリング
  • 手順間の不断の伝達
  • ホットもしくはコールド機能の区別
プロファイルフィードバックは最初にプログラムをコンパイルし、実行、分析されるプログラムを生成してから、収集したデータで最適化を行います。

手順4.4 プロファイルフィードバックの使用

  1. プロファイル情報を作成するには、アプリケーションを -fprofile-generate でコンパイルしてインストルメント化する必要があります。
  2. アプリケーションを実行してプロファイル情報を蓄積し、保存します。
  3. アプリケーションを -fprofile-use で再コンパイルします。
ステップ 3 ではステップ 1 で収集されたプロファイル情報を使ってコンパイラーのヒューリスティックをチューニングする一方で、コードを最終的な実行可能ファイルに最適化します。

手順4.5 プロファイリングフィードバックを使ったプログラムのコンパイル

  1. source.c をコンパイルし、プロファイリングインストルメンテーションを含めます。
    gcc source.c -fprofile-generate -O2 -o executable
  2. executable を実行してプロファイリング情報を収集します。
    ./executable
  3. ステップ 1 で収集したプロファイリング情報を使って source.c を再コンパイル、最適化します。
    gcc source.c -fprofile-use -O2 -o executable
ステップ 2 にあるように、複数のデータ収集の実行はデータを置き換えるのではなく、プロファイリングファイルに蓄積します。これにより、ステップ 2 の実行可能ファイルが追加された対応するデータで複数回実行することが可能になり、より多くの情報が収集できます。
実行可能ファイルは、使用されるマシンと必要な入力に十分な大きさのある対応データセットの両方の典型的なレベルで実行される必要があります。これにより、最善の結果が達成されるようになります。
デフォルトでは、GCC はプロファイルデータをステップ 1 が実行されたディレクトリーに生成します。この情報を別の場所に生成するには、-fprofile-dir=DIR でコンパイルします。この DIR は作成先となるディレクトリーです。

警告

コンパイラーフィードバックデータファイルのフォーマットは、コンパイラーのバージョンにより異なります。コンパイラーの各バージョンでプログラムのコンパイルを繰り返すことが必要となります。

4.1.6.6. 64 ビットホスト上での 32 ビットコンパイラーの使用

64 ビットのホスト上では、GCC は 64 ビットのホスト上でのみ実行可能な実行可能ファイルをビルドします。しかし、GCC を使って 64 ビットと 32 ビットの両方のホスト上で実行可能な実行可能ファイルをビルドすることもできます。
64 ビットのホスト上で 32 ビットのバイナリーをビルドするには、まず実行可能ファイルが必要とするサポート用ライブラリーの 32 ビットバージョンをインストールします。プログラムが C++ プログラムの場合、これは少なくとも glibclibgcclibstdc++ のサポート用ライブラリーを含める必要があります。Intel 64 および AMD64 では、以下のコマンドを実行します。
yum install glibc-devel.i686 libgcc.i686 libstdc++-devel.i686
プログラムが必要とする新たな 32 ビットライブラリーをインストールすることが便利な場合もあります。たとえば、プログラムがビルドに db4-devel を使用する場合、このライブラリーの 32 ビットバージョンは以下のコマンドでインストールできます。
yum install db4-devel.i686

注記

(x86-64 ではなく) x86 プラットフォーム上の .i686 接尾辞は、当該パッケージの 32 ビットバージョンを指定します。PowerPC アーキテクチャーの場合、接尾辞は (ppc64 ではなく) ppc になります。
32 ビットライブラリーのインストール後は、-m32 オプションをコンパイラーとリンカーにパスして 32 ビットの実行可能ファイルが作成できます。64 ビットシステム上にサポート用の 32 ビットライブラリーがインストールされていれば、この実行可能ファイルは 32 ビットシステムと 64 ビットシステムの両方で実行できることになります。

手順4.6 64 ビットホスト上での 32 ビットプログラムのコンパイル

  1. 64 ビットシステム上では、以下のコマンドで hello.c を 64 ビットの実行可能ファイルにコンパイルします。
    gcc hello.c -o hello64
  2. 作成された実行可能ファイルが 64 ビットのバイナリーであることを確認します。
    $ file hello64
    hello64: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
    $ ldd hello64
    linux-vdso.so.1 =>  (0x00007fff242dd000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f0721514000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f0721893000)
    64 ビットの実行可能ファイル上では、コマンド file の出力に ELF 64-bit が含まれ、ldd はリンクされたメイン C ライブラリーとして /lib64/libc.so.6 をリスト表示します。
  3. 64 ビットシステム上では、以下のコマンドで hello.c を 32 ビットの実行可能ファイルにコンパイルします。
    gcc -m32 hello.c -o hello32
  4. 作成された実行可能ファイルが 32 ビットのバイナリーであることを確認します。
    $ file hello32
    hello32: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
    $ ldd hello32
    linux-gate.so.1 =>  (0x007eb000)
    libc.so.6 => /lib/libc.so.6 (0x00b13000)
    /lib/ld-linux.so.2 (0x00cd7000)
    32 ビットの実行可能ファイル上では、コマンド file の出力に ELF 32-bit が含まれ、ldd はリンクされたメイン C ライブラリとして /lib/libc.so.6 をリスト表示します。
32 ビットのサポート用ライブラリがインストールされていなければ、C コードに対して以下のようなエラーが返されます。
$ gcc -m32 hello32.c -o hello32
/usr/bin/ld: crt1.o: No such file: No such file or directory
collect2: ld returned 1 exit status
C++ コードの場合は、以下のようなエラーが返されます。
$ g++ -m32 hello32.cc -o hello32-c++
In file included from /usr/include/features.h:385,
     from /usr/lib/gcc/x86_64-redhat-linux/4.4.4/../../../../include/c++/4.4.4/x86_64-redhat-linux/32/bits/os_defines.h:39,
     from /usr/lib/gcc/x86_64-redhat-linux/4.4.4/../../../../include/c++/4.4.4/x86_64-redhat-linux/32/bits/c++config.h:243,
     from /usr/lib/gcc/x86_64-redhat-linux/4.4.4/../../../../include/c++/4.4.4/iostream:39,
     from hello32.cc:1:
/usr/include/gnu/stubs.h:7:27: error: gnu/stubs-32.h: No such file or directory
これらのエラーは、本セクションの最初の部分で説明されたようにサポート用の 32 ビットライブラリが適切にインストールされていないことを示しています。
また、-m32 でビルドしても、プログラムを適応もしくは変換して 32/64 ビットの互換性から発生する問題の解決にはならないことに注意してください。移動可能なコードの書き込みと、32 ビットから 64 ビットへの変換に関するヒントは、Proceedings of the 2003 GCC Developers SummitPorting to 64-bit GNU/Linux Systems を参照してください。

4.1.7. GCC のドキュメント

GCC コンパイラーについての詳細情報は、cppgccg++gcjgfortran の各コマンドの man ページを参照してください。
また、以下のオンラインユーザーマニュアルも利用可能です。
GCC 開発のメインサイトは gcc.gnu.org です。