gcc詳細編譯過程

2021-10-19 06:58:07 字數 3741 閱讀 5929

2.2 gcc使用語法

2.3 gcc常用選項

2.3.3 改善

3.字尾名決定編譯過程

1.預處理

2.編譯

3.彙編

4.鏈結

我們經常使用「編譯」泛指上面的4個步驟之一,甚至有時候會囊括這四個步驟。

對於嵌入式linux開發來說,用到的程式語言有c,c++,彙編。將乙個大型程式(包含有作業系統)編譯成可執行程式都會經歷這四個步驟:

注意:.s檔案本質上就是二級制檔案(機器碼),.o檔案也是機器碼

git工具大家自行準備。

新增完成後可以使用:gcc -v 命令檢視是否環境變數中已經存在

如果出現上圖所示的資訊就說明已經新增成功了。

gcc [選項] 檔名

gcc hello.c                   // 輸出乙個名為a.out的可執行程式,然後可以執行./a.out

gcc -o hello hello.c // 輸出名為hello的可執行程式,然後可以執行./hello

gcc -o hello hello.c -static // 靜態鏈結

gcc -c -o hello.o hello.c // 先編譯(不鏈結)

gcc -o hello hello.o // 再鏈結

選項

功能-v

檢視gcc編譯器的版本,顯示gcc執行時的詳細過程

-o 指定輸出檔名為file,這個名稱不能跟源檔名同名

-e只預處理,不會編譯、彙編、鏈結t

-s只編譯,不會彙編、鏈結

-c編譯和彙編,不會鏈結

乙個c/c++檔案要經過預處理、編譯、彙編和鏈結才能變成可執行檔案。

(1)預處理

c/c++原始檔中,以「#」開頭的命令被稱為預處理命令,如包含命令「#include」、巨集定義命令「#define」、條件編譯命令「#if」、「#ifdef」等。

預處理就是將要包含(include)的檔案插入原檔案中、將巨集定義展開、根據條件編譯命令選擇要使用的**,最後將這些東西輸出到乙個「.i」檔案中等待進一步處理。

預處理不處理語法錯誤,只是會執行預處理指令(包含標頭檔案,巨集定義,預處理條件開關)

(2)編譯

編譯就是把c/c++**(比如上述的「.i」檔案)「翻譯」成彙編**。

編譯的時候編譯器會檢查語法錯誤。

(3)彙編

彙編就是將第二步輸出的彙編**翻譯成符合一定格式的機器**,在linux系統上一般表現為elf目標檔案(obj檔案)。「反彙編」是指將機器**轉換為彙編**,這在除錯程式時常常用到。

(4)鏈結

鏈結就是將上步生成的obj檔案和系統庫的obj檔案、庫檔案鏈結起來,最終生成了可以在特定平台執行的可執行檔案。

gcc -e -o hello.i hello.c

gcc -s -o hello.s hello.i

gcc -c -o hello.o hello.s

gcc -o hello hello.o

2.3.2.1 對hello.c檔案只進行預處理操作

給出hello.c的源**,如下:

#include #define max 20

#define min 10

#define _debug

#define setbit(x) (1在git裡面用 cat 命令檢視一下。

現在我們已經得到hello.c檔案了,接下來對該檔案只進行預處理命令。

gcc -e -o hello.i hello.c

現在我們來看下hello.i檔案的內容。

擷取hello.i中內容的一部分,我們發現,巨集定義已經被替換了,開關表達語句也消失了,包含標頭檔案命令也被替換了,這就是預編譯器將源程式進行了預處理操作。

注意:預編譯器是不會對語法進行報錯的,僅僅起了乙個替換作用。不信,你可以在原始檔中隨意地修改**,都不會報錯。

2.3.2.2 對hello.i檔案只進行編譯操作

gcc -s -o hello.s hello.i

現在已經得到了彙編檔案。

2.3.2.3 對hello.s檔案只進行彙編操作

gcc -c -o hello.o hello.s

我們再看下hello.o檔案裡面的內容

這裡面的內容你當然看不懂了,看的懂你就是神人。.o檔案裡面的內容是機器碼,顯示出來就會出現稀奇古怪的內容,不用在意。

2.3.2.4 對hello.o檔案只進行鏈結操作

gcc -o hello hello.o

執行完這個命令之後就出現exe檔案了。

2.3.2.5 執行hello.exe檔案

看看,結果是不是和自己預想的一樣。

上面一連串命令比較麻煩,gcc會對.c檔案預設進行預處理操作,使用-c再來指明了編譯、彙編,從而得到.o檔案,

再將.o檔案進行鏈結,得到可執行應用程式。

簡化如下:

gcc -c -o hello.o hello.c

gcc -o hello hello.o

注意:工程(包含很多個檔案)在處理的過程中都是以原始檔為單位。

這種編譯方式有個非常好的一點就是,當你有個檔案修改了,你只需要對那個檔案進行編譯即可,而不需要對整個檔案進行編譯。

標頭檔案在**?

可以自己指定頭檔案目錄

-i 《頭檔案目錄》
庫檔案在**?

可以自己指定庫檔案目錄

-l 《庫檔案目錄》
-l  // 鏈結 libabc.so 或 lib.a
在linux中 ,.o是目標檔案,相當於windows中的.obj檔案 .so 為共享庫,是shared object,用於動態連線的,相當於windows下的dll .a為靜態庫,是好多個.o合在一起,用於靜態連線 。

GCC編譯hello c的詳細過程

gcc help檢視gcc引數用法 e preprocess only do not compile,assemble or link s compile only do not assemble or link c compile and assemble,but do not link o pl...

gcc編譯過程

本文對gcc編譯器如何工作做乙個概要描述.更為詳細的資訊請參考編譯器手冊。當我們進行編譯的時候,要使用一系列的工具,我們稱之為工具鏈.其中包括 預處理器cpp,編譯器前端gcc g 彙編器as,聯結器ld.乙個編譯過程包括下面幾個階段 1 預處理。預處理器cpp將對原始檔中的巨集進行展開。2 編譯。...

gcc編譯過程

當我們進行編譯的時候,要使用一系列的工具,我們稱之為工具鏈.其中包括 預處理器cpp,編譯器前端gcc g 彙編器as,聯結器ld.乙個編譯過程包括下面幾個階段 1 預處理。預處理器cpp將對原始檔中的巨集進行展開。2 編譯。gcc將c檔案編譯成彙編檔案。3 彙編。as將彙編檔案編譯成機器碼。4 連...