[Linux] ツール GCC G++ コンパイラ 簡易用途 (C++)

目次

1. 関連知識の背景

2. GCC のコンパイル プロセスは何ですか?

【2.1】前処理(マクロ置換)

【2.2】コンパイル(アセンブリの生成)

【2.3】接続(実行ファイルまたはライブラリファイルの生成)

3. GCCコマンドの共通オプション

4. 動的リンクと静的リンク


1. 関連知識の背景

gccg++ は、それぞれgnuc および c++コンパイラーであり、 gcc/g++ がコンパイル作業を実行する場合

  • 前処理、.iファイルの生成 [プリプロセッサ cpp]

  • 前処理されたファイルをアセンブリ言語に変換し、ファイル.sを生成する[コンパイラー egcs]

  • オブジェクトコード(マシンコード)へのアセンブリによって生成された.oファイルがあります[アセンブラとして]

  • ターゲットコードを接続し、実行可能プログラムを生成する [linker ld]

>>预处理(进行宏替换) >>编译(生成汇编)  >>汇编(生成机器可识别代码) >>连接(生成可执行文件或库文件) 

テストコードは次のとおりです。

#include <stdio.h>

// 宏定义
#define M 1234
int main(){
    // 注释:
    // 我是注释。                                                                             
    printf("Hello World\n");
    printf("Hello World\n");
    printf("Hello World\n");
    printf("Hello World\n");
    printf("Hello World\n");
    printf("Hello World\n");
    printf("Hello World\n");

#ifdef SHOW 
    printf("Hollo Show\n");
#else
    printf("Hollo Default\n");
#endif
    printf("宏:%d\n", M);
    return 0;
}

[マクロ定義をコンパイルしない]

gcc main.c -o execute
// 执行结果:
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hollo Default
宏:1234

[コンパイルマクロ定義]

gcc main.c -o execute -DSHOW
// 执行结果:
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hollo Show
宏:1234

2. GCC のコンパイル プロセスは何ですか?

【2.1】前処理(マクロ置換)

>> 指令:gcc -E main.c -o main.i
  • 前処理機能には主にマクロ定義、ファイルのインクルード、条件付きコンパイル、コメントの削除などが含まれます。

  • 前処理ディレクティブは、# 記号で始まるコード行です。

  • オプション"-E"。このオプションの機能は、前処理の完了後に gcc にコンパイル プロセスを停止させることです。

  • オプション「-o」はターゲットファイルを指し、「.i」ファイルは前処理されたCオリジナルプログラムです。

【2.2】コンパイル(アセンブリの生成)

>> 指令:gcc –S main.i –o main.s
  • この段階では、gcc はまずコードの標準化や文法上の誤りの有無などをチェックして、コードが実際に実行する作業を決定し、チェックが正しい場合、gcc はコードをアセンブリ言語に変換します。

  • ユーザーは、 「-S」オプションを使用して表示できます。このオプションは、アセンブルせずにコンパイルのみを実行し、アセンブリ コードを生成します。

【2.3】接続(実行ファイルまたはライブラリファイルの生成)

上記の 3 つの手順はコードをコンパイルするだけですが、コードを実行するには、コードを C 標準ライブラリのコードとリンクする必要があります。このプロセスをリンクと呼びます。

>> 指令:gcc main.o –o myMain
// 查看结构
[shaxiang@VM-8-14-centos lesson]$ ls
main.c  main.i  main.o  main.s
// 生成可执行
[shaxiang@VM-8-14-centos lesson]$ gcc main.o -o myMain
[shaxiang@VM-8-14-centos lesson]$ ./myMain 
// main.c 源文件  main.i 预编译文件  main.s 编译文件  main.o 汇编文件  myMain 可执行文件
main.c  main.i  main.o  main.s  myMain
// 执行结果
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hollo Default
宏:1234

3. GCCコマンドの共通オプション

オプション 説明する
-アンシ ANSI 標準の C 構文のみがサポートされます。このオプションは、asm や typeof キーワードなどの GNU C の特定の機能を無効にします。
-c オブジェクト ファイルのみをコンパイルして生成します。
-Dマクロ 文字列「1」を使用して MACRO マクロを定義します。
-DMACRO=DEFN 文字列「DEFN」を使用して MACRO マクロを定義します。
-E C プリコンパイラを実行するだけです。
-g デバッグ情報を生成します。GNU デバッガはこの情報を悪用できます。
-IDIRECTORY 追加のヘッダー ファイル検索パス DIRECTORY を指定します。
-LDIRECTORY 追加のライブラリ検索パス DIRECTORY を指定します。
-lライブラリ 接続時に指定した関数ライブラリLIBRARYを検索します。
-m486 486 用のコードの最適化。
-o ファイル 指定された出力ファイルを生成します。実行可能ファイルを生成するときに使用されます。
-O0 最適化は実行されません。
-O または -O1 生成されたコードを最適化します。
-O2 高度な最適化。
-O3 インライン関数を含む、-O2 よりもさらに最適化されています。
-共有 共有オブジェクト ファイルを生成します。通常、共有ライブラリを構築するときに使用されます。
-静的 共有接続は禁止されています。
- 大きい MACRO マクロの定義を解除します。
-w 警告メッセージは生成されません。
-壁 すべての警告メッセージを生成します。

4. 動的リンクと静的リンク

        この C プログラムでは、「printf」の関数実装は定義されておらず、プリコンパイルに含まれる「stdio.h」には関数の宣言のみがあり、関数の実装は定義されていません。 「printf」関数の実装はどうですか?

        最終的な答えは次のとおりです。システムはこれらの関数を libc.so.6 という名前のライブラリ ファイルに実装します。指定しない場合、gcc はシステムのデフォルトの検索パス "/usr/lib " に移動します。検索、つまり libc へのリンクです。 .so.6のライブラリ関数でprintfという関数を実装できるようにするためのリンクの役割です。

関数ライブラリは一般に、静的ライブラリと動的ライブラリの 2 つのタイプに分類されます。

  • 静的ライブラリとは、コンパイルおよびリンク時にライブラリ ファイルのすべてのコードが実行可能ファイルに追加されるため、生成されるファイルは比較的大きくなりますが、実行時にはライブラリ ファイルが必要なくなります。接尾辞は通常「.a」です。

  • これに対し、ダイナミック ライブラリは、コンパイルおよびリンク時にライブラリ ファイルのコードを実行可能ファイルに追加せず、プログラムの実行時にランタイム リンク ファイルによってライブラリが読み込まれるため、システムのオーバーヘッドを節約できます。動的ライブラリには通常、「.so」という接尾辞が付きます。前述したように、libc.so.6 は動的ライブラリです。gcc はコンパイル時にデフォルトで動的ライブラリを使用します。リンクが完了すると、gcc は実行可能ファイルを生成できます。

gcc によって生成されるバイナリ プログラムはデフォルトで動的にリンクされており、file コマンドを通じて確認できます。

file myMain     // 查看可执行文件的详细信息.
ldd myMain      // 查看可执行文件以来的动态库文件.

                Linux 環境では、ほとんどの命令が動的ライブラリに基づいているため、動的ライブラリは非常に重要です。

>> 命令:file /usr/bin/ls
>> 命令:file /usr/bin/pwd
>> 命令:file /usr/bin/which
>> 命令:ldd /usr/bin/ls

        Linux でコードをコンパイルする場合、デフォルトでダイナミック リンク ライブラリが使用されますが、スタティック ライブラリを使用してコンパイルすることはできますか?

>> 命令:gcc main.c -o myMain_s -static

一般に、静的ライブラリは自分でインストールする必要があります。静的ライブラリのインストール方法のリストは次のとおりです。

  • libc.a がインストールされているかどうかを確認する

>> 命令:sudo find / -name 'libc.a'  
  • システムインストール静的ライブラリ

// centos系列安装
>> 命令:sudo yum install glibc-static   		// 安装C语言静态库
>> 命令:sudo yum install libstdc++-static   	// 安装C++语言静态库
// ubuntu系列安装
>> 命令:sudo apt-get install libc6-dev  
    
// 安装完成后,再次查看静态库
[shaxiang@VM-8-14-centos ~]$ sudo find / -name 'libc.a'
/usr/lib64/libc.a

おすすめ

転載: blog.csdn.net/lx473774000/article/details/132760457