GCC 編譯c程式的方法及過程解析

2022-10-03 09:42:09 字數 3109 閱讀 4718

目前 linux 下最常用的 c 語言編譯器是 gcc ( gnu compiler collection ),它是 gnu 專案中符合 ansi c 標準的編譯系統,能夠編譯用 c 、 c++ 和 object c 等語言編寫的程式。 gcc 不僅功能非常強大,結構也異常靈活。最值得稱道的一點就是它可以通過不同的前端模組來支援各種語言,如j**a 、 fortran 、 pascal 、 modula-3 和 ada 等。開放、自由和靈活是 linux 的魅力所在,而這一點在 gcc 上的體現就是程式設計師通過它能夠更好地控制整個編譯過程。在使用 gcc 編譯程式時,編譯過程可以被細分為四個階段:

預處理( pre-processing )

編譯( compiling )

彙編( asse mbling )

鏈結( linking )txvgoat

linux 程式設計師可以根據自己的需要讓 gcc 在編譯的任何階段結束,以便檢查或使用編譯器在該階段的輸出資訊,或者對最後生成的二進位制檔案進行控制,以便通過加入不同數量和種類的除錯**來為今後的除錯做好準備。和其它常用的編譯器一樣, gcc 也提供了靈活而強大的**優化功能,利用它可以生成執行效率更高的**。

gcc 提供程式設計客棧了 30 多條警告資訊和三個警告級別,使用它們有助於增強程式的穩定性和可移植性。此外, gcc 還對標準的 c 和 c++ 語言進行了大量的擴充套件,提高程式的執行效率,有助於編譯器進行**優化,能夠減輕程式設計的工作量。

c 程式的編譯過程主要分為四個階段:pre-processing,compiling,assembling,linking;

常用檔案的字尾名:

gcc 預處理階段:主要對包含的標頭檔案(#include )和巨集定義(#define,#ifdef … )進行處理。可以使用「gcc -e」 讓gcc 在預處理之後停止編譯過程,生成 *.i 檔案。

[root@localhost gcc]# gcc -e hello.c -o hello.i

gcc 編譯階段:gcc 首先要檢查**的規範性,是否有語法錯誤等。以確定**實際要做的工作,在檢查無誤後,gcc 把**翻譯成組合語言。使用者可以使用-s 選項進行檢視,該選項只進

行編譯而不進行彙編,生成彙編**。

[root@localhost gcc]# gcc -s hello.i -o hello.s

gcc 彙編階段:生成目標** *.o ;有兩種方式:使用 gcc 直接從源**生成目標** gcc -c *.s -o *.o 以及使用彙編器從彙編**生成目標** as *.s -o *.o

[root@localhost gcc]# gcc -c hello.s -o hello.o

[root@localhost gcc]# as hello.s txvgoat-o hello.o

也可以直接使用as *.s, 將執行彙編、鏈結過程生成可執行檔案a.out, 可以像上面使用-o 選項指定輸出檔案的格式。

gcc 鏈結階段:生成可執行檔案;可以生成的可執行檔案格式有: a.out/*/,當然可能還有其它格式。

[root@localhost gcc]# gcc hello.o生成可執行檔案 a.out

[root@localhost gcc]# gcc hello.o -o hello生成可執行檔案 hello

gcc 常用編譯選項:

-dmacro 定義指定的巨集,使它能夠通過原始碼中的 #ifdef 進行檢驗;

-o 、 -o2 、 -o3 將優化狀態開啟,該選項不能與 -g 選項聯合使用;

-v 啟動所有警報,列印編譯過程的資訊;

-wall 在發生警報時取消編譯操作,即將警報看作是錯誤;

-werror 在發生警報時取消編譯操作,即把報警當作是錯誤;

-w 禁止所有的報警。

gcc 鏈結庫檔案的使用

在 linux 下開發軟體時,完全不使用第三方函式庫的情況是比較少見的,通常來講都需要借助乙個或多個函式庫的支援才能夠完成相應的功能。從程式設計師的角度看,函式庫實際上就是txvgoat一些標頭檔案( .h )和庫檔案( .so 或者 .a )的集合。雖然 linux 下的大多數函式都預設將標頭檔案放到/usr/include/ 目錄下,而庫檔案則放到 /usr/lib/ 目錄下,但並不是所有的情況都是這樣。正因如此, gcc 在編譯時必須有自己的辦法來查詢所需要的標頭檔案和庫檔案。 gcc 採用搜尋目錄的辦法來查詢所需要的檔案, -i 選項可以向 gcc 的標頭檔案搜尋路徑中新增新的目錄。例如,如果在/home/justin/include/ 目錄下有編譯時所需要的標頭檔案,為了讓 gcc 能夠順利地找到它們,就可以使用 -i 選項:

# gcc foo.c -i /home/justin/include -o foo

同樣,如果使用了不在標準位置的庫檔案,那麼可以通過 -l 選項向 gcc 的庫檔案搜尋路徑中新增新的目錄。例如,如果在 /home/xiaowp/lib/ 目錄下有鏈結時所需要的庫檔案 libfoo.so ,為了讓 gcc 能夠順利地找到它,可以使用下面的命令:

# gcc foo.c -l /home/justin/lib -lfoo -o foo

值得好好解釋一下的是 -l 選項,它指示 gcc 去連線庫檔案 libfoo.so 。

linux 下的庫檔案在命名時有乙個約定,那就是應該以lib 三個字母開頭,由於所有的庫檔案都遵循了同樣的規範,因此在用-l 選項指定鏈結的庫檔名時可以省去lib 三個字母,也就是說gcc 在對-lfoo 進行處理時,會自動去鏈結名為libfoo.so

linux 下的庫檔案分為兩大類分別是動態鏈結庫(通常以.so 結尾)和靜態鏈結庫(通常以.a 結尾),兩者的差別僅在程式執行時所需的**是在執行時動態載入的,還是在編譯時靜態載入的 。預設情況下,gcc 在鏈結時優先使用動態鏈結庫,只有當動態鏈結庫不存在時才考慮使用靜態鏈結庫,如果需要的話可以在編譯時加上-static 選項,強制使用靜態鏈結庫。例如,如果在home/justin/lib/ 目錄下有鏈結時所需要的庫檔案libfoo.so 和libfoo.a ,為了讓gcc 在鏈結時只用到靜態鏈結庫,可以使用下面的命令:

# gcc foo.c -l /home/justin/lib -static -lfoo -o foo的檔案。

對於動態庫和靜態庫檔案的建立方法,此處不作詳細解釋,可以參考另外一篇linux c 庫檔案建立方法。

本文標題: gcc 編譯c程式的方法及過程解析

本文位址: /ruanjian/c/104736.html

GCC 的編譯過程及編譯工具

nasm的安裝與使用 總結本文講解了gcc的編譯過程,預處理 編譯 彙編和連線。還有編譯工具nasm的使用。include intmain void 預處理語句 gcc e hello.c o hello.ihello.i檔案內容 gcc s hello.i o hello.shello.s檔案內容...

gcc簡介及編譯過程

1 編譯器 gcc 簡介 linux系統下的 gcc gnu c compiler 是gnu推出的功能強大 效能優越的多 平台編譯器,它是gnu的代表作品之一,gcc是可以在多種硬體平台上編譯出可 執行檔案的超級編譯器,其執行效率比一般的編譯器要高出20 30 編譯器能 將c c 語言源程式 組合語...

gcc編譯C 程式

單個原始檔生成可執行程式 下面是乙個儲存在檔案 helloworld.cpp 中乙個簡單的 c 程式的 helloworld.cpp include int main int argc,char argv 程式使用定義在標頭檔案 iostream 中的 cout,向標準輸出寫入乙個簡單的字串。該 可...