gcc編譯器

gcc編譯器


  • GNU CC(簡稱gcc),是GUN項目中符合ANSI C標準的編譯系統。
  • GCC不單單能支持 C 語言;它如今還支持 Ada 語言、C++ 語言、Java 語言、Objective C 語言、Pascal 語言、COBOL語言,以及支持函數式編程和邏輯編程的 Mercury 語言,等等。
  • 並且gcc是一個交叉平臺編譯器,它可以在當前CPU平臺上爲多種不一樣體系結構的硬件平臺開發軟件,所以尤爲適合在嵌入式領域的開發編譯。

gcc編譯流程分爲4個步驟:

  • 預處理(gcc -E)、編譯(gcc -S)、彙編(gcc -c)、連接, gcc 選項能夠簡記爲「ESc」,相應的產出文件的後綴能夠簡記爲「iso」

下面具體看一下gcc是如何完成以上4個步驟的:編程

//test.c函數式編程

#include 
int main(void)
 {
printf("Hello World!\n");
return 0;
}

這個程序,一步到位的編譯指令是:函數

gcc test.c -o test

預處理

運行預處理命令:code

gcc -E test.c -o test.i 或 gcc -E test.c

gcc的-E選項,可讓編譯器在預處理後中止,並輸出預處理結果。開發

gcc的-o選項,用於輸出處理結果到文件中。編譯器

在本例中,預處理結果就是將stdio.h 文件中的內容插入到test.c中了。io

編譯

預處理以後,可直接對生成的test.i文件編譯,生成彙編代碼:編譯

gcc -S test.i -o test.s

gcc的-S選項,表示在程序編譯期間,在生成彙編代碼後,中止,-o輸出彙編代碼文件。test

彙編

gcc -c test.s -o test.o

連接

連接階段,這裏涉及一個重要的概念:函數庫gcc

  • 在這個程序中並無定義「printf」的函數實現,且在預編譯中包含進的「stdio.h」中也只有該函數的聲明,而沒有定義函數的實現,那麼,是在哪裏實現「printf」函數的呢?

  • 最後的答案是:系統把這些函數的實現都放到名爲libc.so.6的庫文件中去了,在沒有特別指定時,gcc會到系統默認的搜索路徑「/usr/lib」下進行查找,也就是連接到libc.so.6函數庫中去,這樣就能調用函數「printf」了,而這也正是連接的做用

函數庫有靜態庫和動態庫兩種

靜態庫是指編譯連接時,將庫文件的代碼所有加入到可執行文件中,所以生成的文件比較大,但在運行時也就再也不須要庫文件了,其後綴名一般爲「.a」。

動態庫與之相反,在編譯連接時並無將庫文件的代碼加入到可執行文件中,而是在程序執行時加載,這樣能夠節省系統的開銷。通常動態庫的後綴名爲「.so」,如前面所述的libc.so.6就是動態庫。gcc在編譯時默認使用動態庫。

對於上一小節中生成的test.o,將其與C標準輸入輸出庫進行鏈接,最終生成程序test:

gcc test.o -o test

多個程序文件的編譯

一般整個程序是由多個源文件組成的,相應地也就造成了多個編譯單元,使用GCC可以很好地管理這些編譯單元。假設有一個由test1.c和 test2.c兩個源文件組成的程序,爲了對它們進行編譯,並最終生成可執行程序test,可使用下面這條命令:

gcc test1.c test2.c -o test

若是同時處理的文件不止一個,GCC仍然會按照預處理、編譯和連接的過程依次進行。若是深究起來,上面這條命令大體至關於依次執行以下三條命令:

gcc -c test1.c -o test1.o
gcc -c test2.c -o test2.o
gcc test1.o test2.o -o test
相關文章
相關標籤/搜索