linux gcc 的編譯過程 詳解

來源:互聯網
上載者:User

gcc的編譯過程分為四步,分別為:
(1)先行編譯 (Pre-Processing)
(2)編譯 (Compiling)
(3)彙編 (Assembling)
(4)連結 (Linking)
以hello.c為例說明:
#include<stdio.h>
int main(void)
{
 printf("Hello World!");
 return 0;
}

(1)先行編譯階段 (Pre-Processing)
  在該階段,編譯器將上述代碼中的stdio.h編譯進來,並且使用gcc -E進行查看(-E讓gcc在預先處理結束後停止編譯)
  gcc -E hello.c -o hello.i
  查看hello.i可見,gcc確實進行了預先處理,它把"stdio.h"的內容插入到hello.i檔案中
(2)編譯階段
  在這個階段,gcc首先檢查代碼的規範性,是否有語法錯誤等,以確定代碼的實際要做的工作,在檢查無誤後
  gcc把代碼編譯成組合語言,可以使用-S選項進行查看,該選項之進行編譯而不進行彙編,產生彙編代碼
  gcc -S hello.i -o hello.s
(3)彙編階段
 就是把編譯階段產生的.s檔案轉成目標檔案,可以使用選項-c ,就是把彙編代碼轉化成.o的二進位目標代碼了
 gcc -c hello.s -o hello.o

(4)連結階段
 在成功編譯之後就進入了連結階段,在這裡涉及到一個重要的概念:函數庫。
 讀者重新查看這個小程式,在該小程式中沒有並沒有定義"printf"的函數實現,且在先行編譯中包含進的"stdio.h"
 中也只有該函數的聲明,而沒有定義該函數的實現,那麼在哪實現"printf"函數哪?,最後答案是:系統把這些函數實現
 都被做到名為libc.so.6的庫檔案中去了,在沒有特別指定時gcc會到系統預設的搜尋路徑"/usr/lib"下去尋找
 也就是連結到libc.so.6庫函數中去,這樣就實現了"printf"了,而這也是連結的作用
 函數庫一般分為靜態庫和動態庫兩種,靜態庫是指在編譯連結時,把庫檔案的代碼全部加到可執行程式中去,因此產生的
 可執行檔比較大,在運行時就不再需要庫檔案了,尾碼名為.a。動態庫與之相反,在編譯連結時並沒有把庫檔案的代碼
 加入到可執行檔中,而是在程式執行時由運行時連結檔案載入庫,這樣可以節省系統的開銷,動態庫一般尾碼名為.so。
 完成連結後gcc就可以產生可執行檔

gcc hello.o -o hello

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.