gccコンパイラ基礎学習ノート


概要
Linuxシステム下のgcc(GNU C Compiler)は、GNUが発売した機能が強く、性能が優れたマルチプラットフォームコンパイラであり、GNUの代表作の一つである.gccは複数のハードウェアプラットフォーム上で実行可能プログラムをコンパイルすることができ、その実行効率は一般的なコンパイラに比べて平均効率が20%~30%高い.
一、ファイルタイプ
gccは接尾辞で入力ファイルのカテゴリを区別し,gccが従う部分的な約束規則を紹介する.
.cは接尾辞のファイルであり、C言語ソースファイルである.
.aは接尾辞のファイルであり、ターゲットファイルからなるリポジトリファイルである.
.C,.ccまたは.cxxは接尾辞のファイルで、C++ソースコードファイルです.
.hは接尾辞のファイルであり、プログラムに含まれるヘッダファイルである.
.iは接尾辞のファイルであり、すでに前処理されたCソースファイルである.
.iiは接尾辞のファイルであり、すでに前処理されたC++ソースコードファイルである.
.mは接尾辞のファイルで、Objective-Cソースファイルです.
.oは接尾辞のファイルであり、コンパイル後のターゲットファイルである.
.sは接尾辞のファイルであり、アセンブリ言語ソースファイルである.
.Sは接尾辞のファイルであり、プリコンパイルされたアセンブリ言語ソースファイルである.
二、コンパイルプロセス
gccコンパイラを使用する場合、コンパイルプロセスは4つの段階に細分化されます.
(1)前処理(プリコンパイル、Preprocessingとも呼ばれる)
(2)コンパイル(Compilation)
(3)アセンブルアセンブル(Assembly)
(4)リンク(Linking)
ここはハローcを例とする:
#include 
int main(void)
{
printf (Hello world!
); return 0; }

1、前処理:
前処理フェーズでは、コンパイラはコードのstdioを.hのコードがコンパイルされ、ユーザーは-Eオプションを使用して表示する
gcc -E hello.c -ohello.i
2、コンパイル:
gccはまず文法の規範性や文法の誤りがあるかどうかなどを検査して、コードが実際にしなければならない仕事を確定して、誤りがないことを検査した後、gccはコードをアセンブリ言語にコンパイルします.
gcc -S hello.i -o hello.s
3、アセンブリ
コンパイルを生成する.sファイルをターゲットファイルに変換
gcc -c hello.s -ohello.o
 
4、リンク
このフェーズでは、ここで重要な概念である関数ライブラリについて説明します.このプログラムでは「printf」の関数実装は定義されておらず、プリコンパイルに含まれる「stdio.h」にもその関数の宣言のみがあり、関数実装は定義されておらず、どこで「printf」が実装されるのか関数は?最後の答えは:システムはこれらの関数の実現をlibcという名前に入れた.so.6のライブラリファイルに行きました.特に指定されていない場合、ライブラリ関数に行きます.GCCはシステムのデフォルトの検索パス「/usr/Iib」の下で検索します.つまりlibcにリンクします.so.6これで関数「printf」が実現し,これがリンクの役割である.
gcc  hello.o –o hello
初心者はコマンドラインから始めたほうがいいです.これにより、プログラムの作成、コンパイル、デバッグ、実行のプロセス全体を熟知することができます.プログラミングプログラムはviまたは他のエディタで作成できます.コンパイルではgccコマンドを使用します.
三、gccコマンドの使い方
gccコマンドは非常に多くのコマンドオプションを提供していますが、すべてを熟知しなければならないわけではありません.初心者はいくつかのよく使われているものをマスターすればいいので、後で他のオプションをゆっくり勉強して、オプションが多すぎて学習の自信に打撃を与えないようにします.
共通コンパイルコマンドオプション
 
ソースプログラムのファイル名をtestとする.c.
1.オプションなしでリンクをコンパイル
用法:#gcc test.c
作用:test.c実行可能ファイルを前処理、アセンブリ、コンパイル、リンクして形成する.ここでは出力ファイルは指定されておらず、デフォルト出力はa.outです.
2.オプション-o
用法:#gcc test.c -o test
作用:test.c実行可能ファイルtestを形成する前処理、アセンブリ、コンパイル、リンク.-oオプションは、出力ファイルのファイル名を指定します.
3.オプション-E
用法:#gcc-E test.c -o test.i
作用:test.c前処理出力test.iファイル.
4.オプション-S
用法:#gcc-S test.i 
役割:前処理をファイルtestに出力.i編成test.sファイル.
5.オプション-c
用法:#gcc-c test.s
作用:アセンブリ出力ファイルtest.sコンパイル出力test.oファイル.
6.オプションリンクなし
用法:#gcc test.o -o test
作用:出力ファイルtestをコンパイルする.o最終実行可能ファイルtestにリンクします.
8.オプション-O
用法:#gcc-O 1 test.c -o test
役割:コンパイル最適化レベル1コンパイラを使用します.レベルは1~3で、レベルが大きいほど最適化効果は良いが、コンパイル時間が長くなる.
9.オプション-O 2
-Oよりもコンパイル、リンクを最適化し、もちろんコンパイル、リンクプロセス全体が遅くなります.
10.オプション-g
gcc-gシンボルデバッグツール(GNUのgdb)に必要なシンボル情報を生成するには、ソースコードをデバッグするには、このオプションを追加する必要があります.
11.-Idirname
dirnameが示すディレクトリをプログラムヘッダファイルディレクトリリストに追加するのは、プリコンパイル中に使用されるパラメータです.Cプログラムのヘッダファイルには、2つのケースがあります.
A)#include
B)#include "myinc.h"
ここで、Aクラスは括弧()、Bクラスは二重引用符(""")を使用します.Aクラスの場合、プリプロセッサcppは、/usr/includeなどのシステムプリセットに含まれるファイルディレクトリで対応するファイルを検索します.
Bクラスの場合、cppは現在のディレクトリでヘッダファイルを検索します.このオプションの役割は、cppに、現在のディレクトリに必要なファイルが見つからない場合は、指定したdirnameディレクトリで検索するように伝えることです.プログラム設計では、このような含むファイルがそれぞれ異なるディレクトリに分散する必要がある場合は、-Iオプションを使用して検索パスを1つずつ指定する必要があります.例:gcc foo.c -I/home/include -o foo
12.-Ldirname
dirnameが示すディレクトリをプログラム関数リポジトリファイルのディレクトリリストに追加するのは、接続中に使用されるパラメータです.プリセット状態では、接続プログラムldは、/usr/libなどのシステムのプリセットパスで必要なリポジトリファイルを探します.このオプションは、接続プログラムに、まず-Lで指定したディレクトリで探し、その後、システムプリセットパスで探し、関数在庫が複数のディレクトリの下にある場合、このオプションを順次使用して、対応する格納ディレクトリを与える必要があることを示します.
-lname、接続時に「libname.a」という名前の関数ライブラリをロードします.この関数ライブラリは、システムが予め設定したディレクトリまたは-Lオプションによって決定されたディレクトリの下にあります.たとえば、-lmは「libm.a」という名前の接続の数学関数ライブラリを表します.
例:gcc test.c -L/home/lib –lfoo -o test
13.staticオプション
GCCはデフォルトでダイナミックライブラリにリンクされています.ダイナミックライブラリをリンクすることなく、いくつかの関数をプログラムに静的にコンパイルするために-staticオプションを使用する場合があります.これにより、静的ライブラリへの接続が強制されます.