GCC編譯過程
GCC是Linux上功能最強大的C語言編譯器,在使用GCC編譯程序的時候,編譯過程分為4個階段:
預處理(Pre-Processing)
這一步,GCC調用預處理程序cpp,將源文件中定義的宏展開,並將#include頭文件的內容插入源文件,生成一個以.i為後綴的新文件。
GCC -E 源碼文件 -o 預處理生成文件
編譯(Compiling)
這一步,GCC調用ccl程序將預處理生成的.i文件編譯成以.s為後綴的匯編文件。
GCC -S 預處理後的文件/源文件 -o 匯編文件
匯編(Assembling)
這一步,GCC調用as程序將.s文件匯編成機器代碼.o的目標文件。
GCC -c 預處理後的文件/匯編文件/源文件 (-o 目標文件)
鏈接(Linking)
這一步,GCC將調用ld程序將所有的目標文件鏈接成一個可執行程序。
GCC 所有目標文件 -o 可執行程序名稱
以上是GCC編譯一個源文件的四個步驟,但現實的項目中往往會有很多的源碼文件,如果使用命令行方式一個一個編譯,不僅費時費力,還很容易出問題,這時候就需要使用到make這個工具,在本文中暫不討論make這個工具。
GCC警告信息
GCC提供了警告功能,包含完整的錯誤檢查,可以幫助我們檢查出一些潛在的錯誤,從而幫助我們寫出更加專業和優美的代碼。
GCC能夠提供很多種警告信息,其中最有用的當屬-Wall了,使用這個選項可以使GCC產生盡可能多的警告信息。這些警告從嚴格意義上說算不上是錯誤,但可能會是潛在的錯誤,這裡就引出另外比較有用的選項-Werror,帶上這個選項,GCC會在出現警告的地方停止編譯。
庫依賴
在程序開發中經常會使用到一些第三方庫,特別在開放的Linux平台上更甚。從程序上來看,第三方庫其實就是一些頭文件和一些庫文件的集合,在程序中include頭文件,編譯的時候鏈接庫文件。在Linux下大多數函數都默認將頭文件放在/usr/include/目錄下,將庫文件放在/usr/lib/下,但這並不能代表所有的情況,所以GCC在編譯時需要有其他的方法來查找需要的頭文件與庫文件。
GCC是采用的搜索目錄的方式來查找所需文件,-l可以向GCC頭文件搜索路徑添加目錄,-L添加庫文件目錄,格式如下例:
GCC -c main.c -l /home/include/
GCC -c main.c -L /home/lib/ -l**, -l**是一個約定俗成的用法,Linux下面所有的庫應該以lib開頭,比如libtest.so或者libtest.a,那麼鏈接的時候就使用 -ltest 即可,GCC會自動找到libtest.so或者libtest.a,GCC會默認使用動態鏈接,只有指定 -static 選項時,才會強制使用靜態鏈接庫。
GCC代碼優化
GCC可以通過設置-On選項對源碼進行優化,不同的n值代表不同的優化級別
編譯時使用 -O 等價與 -O1 的效果,告訴GCC減小代碼長度和執行時間。
使用-O2,除了O1的效果外,還要做一些額外的優化,比如調整處理器指令調度等。
-O3在O2基礎上,會做一些循環展開和與處理器特性相關的優化工作。
n值越高,優化會做得愈徹底,這也意味著原有的代碼結構可能會被改變,所以優化將會給程序的調試和跟蹤帶來困難。
調試
利用GCC的 -g 選項可以生成調試信息便於使用GDB調試程序。