gcc 編譯器簡介

Linux中選擇gcc編譯器的原因是gcc執行效率高。
gcc基本用法:gcc [options] filename
其中options爲編譯選項。
例子:執行指令 gcc hello.c ,則對hello.c進行編譯,如果程序沒有語法錯誤,則產生可執行文件a.out(gcc默認文件名)
運行可執行文件指令:./a.out

gcc編譯器將c/c++源程序、彙編程序形成可執行文件經過四個階段:預處理、編譯、彙編、鏈接。
預處理:該階段編譯器將程序中包含的頭文件編譯進來,編譯選項爲-E
例如:gcc -E hello.c -o hello.i
編譯:該階段編譯器檢查程序代碼規範性、是否存在語法錯誤等,以確定代碼要做的工作,在檢查無誤後,gcc編譯器將代碼編譯成彙編語言,編譯選項爲S(大寫)。
例如:gcc -S hello.i -o hello.s
彙編:該階段將編譯階段中產生的彙編文件轉化爲二進制目標文件,編譯選項爲-c
例如:gcc -c hello.s -o hello.o
鏈接:將目標文件鏈接成可執行文件
例如:gcc hello.o -o hello
鏈接中涉及到一個重要的概念:函數庫
在我們編寫的程序中沒有定義”printf”的函數實現,且在預編譯中包含進來的頭文件”stdio.h”中也只有該函數的聲明,而沒有定義函數的實現,那麼,是在哪裏實現”printf”函數的呢?最後的答案是:系統把這些函數實現都做到名爲libc.so.6的庫文件中去了,在沒有特別指定時,gcc會到系統默認的搜索路徑”/usr/lib”下進行查找,也就是鏈接到libc.so.6庫函數中,這樣就能實現函數”printf” 了,而這也就是鏈接的作用。
函數庫一般分爲靜態庫和動態庫兩種。靜態庫是指編譯鏈接時,把庫文件的代碼全部加入到可執行文件中,因此生成的文件比較大,但在運行時也就不再需要庫文件了。其後綴名一般爲”.a”。動態庫與之相反,在編譯鏈接時並沒有把庫文件的代碼加入到可執行文件中,而是在程序執行時加載庫,這樣可以節省系統的開銷。動態庫一般後綴名爲”.so”,如前面所述的libc.so.6就是動態庫。gcc在編譯時默認使用動態庫。

文件默認類型:
xxx.c:C語言源代碼文件
xxx.a:由目標文件構成的庫文件
xxx.C,xxx.cc,xxx.cxx:c++源代碼文件
xxx.h:頭文件
xxx.o:目標文件
xxx.s:彙編語言源代碼文件

編譯選項:
-o output_filename:確定輸出文件名爲output_filename
-O:對程序進行優化編譯、鏈接,當然,優化編譯、鏈接需要的時間會變長
-O2:更加深入的優化編譯、鏈接。
ps:優化是對程序中多餘的變量、浪費的空間進行處理,把程序變爲語句最少、佔用內存量少、處理速度快、外部設備分時使用效率高的最優程序
-c:不鏈接(即只進行預處理、編譯、彙編)
-g:產生調試工具gdb所需要的符號信息
-I dirname:將dirname所指出的目錄作爲編譯器尋找頭文件的標準路徑。
例如:gcc hello.c -I /home/include -o hello
#include<a.h> //gcc在系統預設的頭文件目錄(如/usr/include)中尋找頭文件
#include"b.h" //gcc在當前目錄中尋找頭文件,-I作用爲當gcc在當前目錄中沒有尋找到需要頭文件時,就到/home/include目錄下尋找。
每一個編譯器都有一個或幾個尋找頭文件的標準路徑。
-w:不生成任何警告信息
-Wall:生成所有警告信息

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章