<b>1.3 gcc的工作流程</b>
在着手構造編譯系統之前,需要先介紹編譯系統應該做的事情,而最具參考價值的資料就是主流編譯器的實作。gnu的gcc編譯器是工業化編譯器的代表,是以我們先了解gcc都在做什麼。
我們寫一個最簡單的“helloworld”程式,代碼存儲在源檔案hello.c中,源檔案内容如下:
#include<stdio.h>
int main()
{
printf("hello world!");
return 0;
}
如果将hello.c編譯并靜态連結為可執行檔案,使用如下gcc指令直接編譯即可:
$gcc hello.c –o
hello -static
hello即編譯後的可執行檔案。
如果檢視gcc背後的工作流程,可以使用--verbose選項。
hello –static --verbose
輸出的資訊如下:
$cc1 -quiet
hello.c -o hello.s
$as -o hello.o
hello.s
$collect2
-static -o hello \
crt1.o crti.o crtbegint.o hello.o \
--start-group libgcc.a libgcc_eh.a libc.a
--end-group \
crtend.o crtn.o
為了保持輸出資訊的簡潔,這裡對輸出資訊進行了整理。可以看出,gcc編譯背後使用了cc1、as、collect2三個指令。其中cc1是gcc的編譯器,它将源檔案hello.c編譯為hello.s。as是彙編器指令,它将hello.s彙編為hello.o目标檔案。collect2是連結器指令,它是對指令ld的封裝。靜态連結時,gcc将c語言運作時庫(crt)内的5個重要的目标檔案crt1.o、crti.o、crtbegint.o、crtend.o、crtn.o以及3個靜态庫libgcc.a、libgcc_eh.a、libc.a連結到可執行檔案hello。此外,cc1在對源檔案編譯之前,還有預編譯的過程。
是以,我們從預編譯、編譯、彙編和連結四個階段檢視gcc的工作細節。