2.2. GCC でのコードのビルド


ソースコードを実行可能コードに変換する必要がある状況を説明します。

2.2.1. コード形式間の関係

C 言語と C++ 言語には、ビルドプロセスの各段階で作成される 3 つの形式のコードがあります。これらの関係を理解すると、GCC を効果的に使用できるようになります。

C 言語および C++ 言語には、以下の 3 つのコード形式があります。

  • C 言語または C++ 言語で記述された ソースコード。プレーンテキストファイルとして表示されます。

    このファイルは通常、.c.cc.cpp.h.hpp.i.inc などの拡張子を使用します。サポートされる拡張子およびその解釈のリストは、gcc の man ページを参照してください。

    $ man gcc
  • コンパイラー でソースコードを コンパイル して作成する オブジェクトコード。これは中間形式です。

    オブジェクトコードファイルは、拡張子 .o を使用します。

  • リンカー でオブジェクトコードを リンク して作成する 実行可能なコード

    Linux アプリケーションの実行可能ファイルは、ファイル名の拡張子を使用しません。共有オブジェクト (ライブラリー) の実行可能ファイルは、.so のファイル名の拡張子を使用します。

注記

静的リンク用のライブラリーアーカイブファイルも存在します。これは、ファイル名拡張子 .a を使用するオブジェクトコードのバリアントです。静的リンクは推奨されません。静的リンクおよび動的リンク を参照してください。

ソースコードから実行可能コードを生成するには、次の 2 つのステップを実行します。それぞれ異なるアプリケーションまたはツールが必要です。

  1. ソースファイルをオブジェクトファイルにコンパイルします。
  2. オブジェクトファイルとライブラリーをリンクします (以前にコンパイルしたソースを含む)。

GCC は、コンパイラーとリンカーのどちらにも、インテリジェントドライバーとして使用できます。これにより、必要なアクション (コンパイルおよびリンク) に gcc コマンドを 1 つ使用できます。GCC はアクションとそのシーケンスを自動的に選択します。

GCC では、コンパイルのみ、リンクのみ、または両方のステップを実行できます。これは、入力タイプや必要とされる出力タイプにより決定されます。

大規模なプロジェクトには、アクションごとに個別に GCC を実行するビルドシステムが必要なため、GCC が両方同時に実行できる場合でも 2 つの異なるアクションとしてコンパイルとリンクを実行することを検討することが推奨されます。

2.2.2. オブジェクトコードへのソースファイルのコンパイル

オブジェクトコードファイルを、実行ファイルから直接作成するのではなく、ソースファイルから作成するには、GCC で、オブジェクトコードファイルのみを出力として作成するように必要があります。このアクションは、大規模なプロジェクトのビルドプロセスの基本操作となります。

前提条件

手順

  1. ターミナルで、ソースコードファイルが含まれているディレクトリーを開きます。
  2. -c オプションを指定して gcc を実行します。

    $ gcc -c source.c another_source.c

    オブジェクトファイルは、オリジナルのソースコードファイルを反映したファイル名を使用して作成されます。source.csource.o になります。

    注記

    C++ ソースコードの場合は、標準 C++ ライブラリーの依存関係を処理しやすくするために、gcc コマンドを g++ に置き換えます。

2.2.3. GCC で C および C++ のアプリケーションのデバッグの有効化

コンパイラーはバイナリーのサイズを抑えるために、デフォルトでデバッグ情報を省略します。GCC を使用した C および C++ のアプリケーションのデバッグを有効にするには、コンパイラーに対して、デバッグデータを作成するように、明示的に指示する必要があります。

手順

  • GCC を使用して C または C++ アプリケーションをコンパイルおよびリンクするときにデバッグ情報を生成するには、コンパイルコマンドに -g オプションを追加します。

    $ gcc ... -g ...

    このオプションは、出力のバイナリーにデバッグ情報を含めるように GCC に指示します。-g オプションと追加のデバッグオプションの詳細は、GCC の man ページを参照してください。

  • デバッグ情報にマクロの定義を含めるには、-g の代わりに -g3 オプションを使用します。

    $ gcc ... -g3 ...
  • デバッグオプションが実行可能コードに影響を与えないことをテストするには、-fcompare-debug GCC オプションを使用します。このオプションは以下を実行します。

    • コードを 2 回コンパイルします。1 回はデバッグ情報あり、もう 1 回はデバッグ情報なしでコンパイルします。
    • 結果のバイナリーファイルを比較します。
    • 両方のバイナリーが同一であればテスト合格とします。

      このテストは、デバッグオプションによってコードに隠れたバグが混入するのを防ぐものです。-fcompare-debug を使用すると、コンパイル時間が大幅に長くなることに注意してください。詳細は、GCC の man ページを参照してください。

      重要

      コンパイラーとリンカーを最適化すると、次の要因によってデバッグが困難になる場合があります。* 使用されていないように見える変数の削除 * ループの展開 * 操作のマージ * ソースコードと実行可能コードの関係の変更

      デバッグエクスペリエンスを向上させるには、-Og オプションの使用を検討してください。ただし、最適化レベルを変更すると、実行可能コードの動作が変わり、バグが隠れてしまう可能性があります。

2.2.4. GCC でのコードの最適化

1 つのプログラムは、複数の機械語命令シーケンスに変換できます。コンパイル時にコードを分析するためにより多くのリソースを割り当てると、より最適な結果が得られます。

GCC では、-Olevel オプションを使用して最適化レベルを設定できます。このオプションでは、level の部分に値を指定できます。

Expand
レベル説明

0

コンピレーション速度の最適化 - コードの最適化なし (デフォルト)

123

最適化して、コード実行速度を向上させます (数値が大きいほど、速度は高くなります)。

s

ファイルサイズを最適化します。

fast

レベルを 3 にして、fast にすると、厳密な標準準拠を無視して追加の最適化を可能にします

g

デバッグ作業の最適化

リリースビルドの場合は、最適化オプション -O2 を使用します。

開発中は、-Og オプションは、状況によってはプログラムまたはライブラリーをデバッグするのに役立ちます。バグによっては、特定の最適化レベルでのみ出現するため、リリースの最適化レベルでプログラムまたはライブラリーをテストしてください。

GCC では、個別の最適化を有効にするオプションが多数含まれています。詳細は、gcc man ページを参照してください。

2.2.5. GCC でコードを強化するオプション

コンパイラーで、ソースコードをオブジェクトコードに変換する場合には、さまざまなチェックを追加して、一般的に悪用される状況などを回避し、セキュリティーを強化できます。適切なコンパイラーオプションセットを選択すると、ソースコードを変更せずに、よりセキュアなプログラムやライブラリーを作成できます。

リリースバージョンのオプション

Red Hat Enterprise Linux を使用する開発者には、以下のオプションリストが推奨される最小限のオプションとなります。

$ gcc ... -O2 -g -Wall -Wl,-z,now,-z,relro -fstack-protector-strong -fstack-clash-protection -D_FORTIFY_SOURCE=3 ...
  • プログラムの場合は、-fPIE および -pie の位置独立実行可能オプションを追加します。
  • 動的にリンクされたライブラリーの場合は、必須の -fPIC (位置独立コード) オプションを使用すると間接的にセキュリティーが強化されます。
開発オプション

開発時にセキュリティーの欠陥を検出する場合は、以下のオプションを使用します。これらのオプションは、リリースバージョンのオプションと併せて使用してください。

$ gcc ... -Walloc-zero -Walloca-larger-than -Wextra -Wformat-security -Wvla-larger-than ...
-fhardened
GCC 14 では新しいフラグ -fhardened が提供され、これにより他の多くのフラグが有効になり、ABI に影響を与えずに生成されたコードのセキュリティーが向上します。
-fanalyzer
GCC には、セキュリティー関連の問題を含む、ソースコード内の潜在的な問題に関する警告をトリガーするフラグ -fanalyzer が用意されています。-fanalyzer では誤検出や検出漏れが頻繁に発生するため、正式な解析ツールとしてではなく、詳細な調査が必要な潜在的なバグを見つけるための参考ツールとして使用する必要があります。このフラグにより、コンパイル中に使用される時間とメモリーが大幅に増加します。C コードでのみ使用してください。

2.2.6. 実行ファイルを作成するコードのリンク

C または C++ のアプリケーション構築の最後の手順は、リンクです。リンクにより、オブジェクトファイルやライブラリーがすべて実行可能ファイルに統合されます。

前提条件

手順

  1. オブジェクトコードファイルを含むディレクトリーに移動します。
  2. gcc を実行します。

    $ gcc ... objfile.o another_object.o ... -o executable-file

    executable-file という名前の実行ファイルが、指定したオブジェクトファイルとライブラリーをベースに作成されます。追加のライブラリーをリンクするには、オブジェクトファイルのリストの後に必要なオプションを追加します。

    詳細は、GCC でのライブラリーの使用 を参照してください。

    注記

    C++ ソースコードの場合は、標準 C++ ライブラリーの依存関係を処理しやすくするために、gcc コマンドを g++ に置き換えます。

2.2.7. 例: GCC で C プログラムの構築 (1 つの手順でコンパイルとリンク)

以下の例では、簡単な C のサンプルプログラムを構築する手順を説明します。

この例では、コードをコンパイルおよびリンクする方法を 1 つの手順で行います。

手順

  1. ディレクトリー hello-c を作成します。

    $ mkdir hello-c
  2. 作成されたディレクトリーに変更します。

    $ cd hello-c
  3. 以下の内容を含む hello.c ファイルを作成します。

    #include <stdio.h>
    
    int main() {
      printf("Hello, World!\n");
      return 0;
    }
  4. GCC でコードをコンパイルし、リンクします。

    $ gcc hello.c -o helloworld

    これにより、コードがコンパイルされ、オブジェクトファイル hello.o が作成され、オブジェクトファイルから実行ファイル helloworld がリンクされます。

  5. 作成された実行可能ファイルを実行します。

    $ ./helloworld
    Hello, World!

2.2.8. 例: GCC を使用した C プログラムの構築 (2 つの手順でコンパイルとリンク)

以下の例では、簡単な C のサンプルプログラムを構築する手順を説明します。

この例では、コードのコンパイルとリンクは、2 つの別個のステップです。

手順

  1. ディレクトリー hello-c を作成します。

    $ mkdir hello-c
  2. 作成されたディレクトリーに変更します。

    $ cd hello-c
  3. 以下の内容を含む hello.c ファイルを作成します。

    #include <stdio.h>
    
    int main() {
      printf("Hello, World!\n");
      return 0;
    }
  4. GCC でコードをコンパイルします。

    $ gcc -c hello.c

    オブジェクトファイル hello.o が作成されます。

  5. オブジェクトファイルから実行可能ファイル helloworld をリンクします。

    $ gcc hello.o -o helloworld
  6. 作成された実行可能ファイルを実行します。

    $ ./helloworld
    Hello, World!
  7. オプション: 親ディレクトリーに戻ります。

    $ cd ..
  8. オプション: hello-c ディレクトリーを削除します。

    $ rm -r hello-c

2.2.9. 例: GCC で C++ プログラムの構築 (1 つの手順でコンパイルとリンク)

以下の例では、最小限の C++ プログラムのサンプルを構築する手順を説明します。

この例では、コードをコンパイルおよびリンクする方法を 1 つの手順で行います。

手順

  1. hello-cpp ディレクトリーを作成します。

    $ mkdir hello-cpp
  2. 作成されたディレクトリーに変更します。

    $ cd hello-cpp
  3. 以下の内容を含む hello.cpp ファイルを作成します。

    #include <iostream>
    
    int main() {
      std::cout << "Hello, World!\n";
      return 0;
    }
  4. g++ でコードをコンパイルし、リンクします。

    $ g++ hello.cpp -o helloworld

    これにより、コードがコンパイルされ、オブジェクトファイル hello.o が作成され、オブジェクトファイルから実行ファイル helloworld がリンクされます。

  5. 作成された実行可能ファイルを実行します。

    $ ./helloworld
    Hello, World!
  6. オプション: 親ディレクトリーに戻ります。

    $ cd ..
  7. オプション: hello-cpp ディレクトリーを削除します。

    $ rm -r hello-cpp

2.2.10. 例: GCC を使用した C++ プログラムの構築 (2 つの手順でコンパイルとリンク)

以下の例では、最小限の C++ プログラムのサンプルを構築する手順を説明します。

この例では、コードのコンパイルとリンクは、2 つの別個のステップです。

手順

  1. hello-cpp ディレクトリーを作成します。

    $ mkdir hello-cpp
  2. 作成されたディレクトリーに変更します。

    $ cd hello-cpp
  3. 以下の内容を含む hello.cpp ファイルを作成します。

    #include <iostream>
    
    int main() {
      std::cout << "Hello, World!\n";
      return 0;
    }
  4. g++ でコードをコンパイルします。

    $ g++ -c hello.cpp

    オブジェクトファイル hello.o が作成されます。

  5. オブジェクトファイルから実行可能ファイル helloworld をリンクします。

    $ g++ hello.o -o helloworld
  6. 作成された実行可能ファイルを実行します。

    $ ./helloworld
    Hello, World!
  7. オプション: 親ディレクトリーに戻ります。

    $ cd ..
  8. オプション: hello-cpp ディレクトリーを削除します。

    $ rm -r hello-cpp
Red Hat logoGithubredditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。 最新の更新を見る.

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

Theme

© 2026 Red Hat
トップに戻る