目次
【2.3】接続(実行ファイルまたはライブラリファイルの生成)
1. 関連知識の背景
gccとg++ は、それぞれgnuのc および 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