Linux編譯器-gcc-g

2024年2月6日 18点热度 0人点赞

前言

gcc/g 是Linux中的編譯器,vim是Linux中的編輯器。要想將代碼運行起來還需要編譯才可實現。 本篇文章,主要通過預處理、編譯、匯編、鏈接來介紹gcc/g 。

預處理

預處理是進行宏替換

  • 功能:主要包括宏定義,文件包含,條件編譯,去註釋
  • 預處理指令都是以#開頭的代碼行
  • 指令(舉例):gcc -E test.c -o test.i

指令解釋:

-E是讓 gcc 在預處理結束後停止編譯過程

-o是指目標文件,“.i”文件為已經過預處理的C原始程序

通過vim test.i進入到test.i

頭文件展開

頭文件展開是把頭文件中的內容拷貝到源代碼中,編譯前系統中必須要有頭文件。頭文件是開發環境中的一部分,不需要我們自己去配置。

Linux系統下,gcc/g 頭文件默認路徑: /usr/include/,去查看它即可

條件編譯

有一個很深刻的印象,在下載安裝pycharm時,需要選擇安裝社區版還是專業版。在社區版和專業版之間,社區版的功能比專業版的功能上少一點,因為社區版有些功能被裁減了。少的這些功能就是通過條件編譯裁剪掉的,如果沒有條件編譯,那針對每一個版本,廠商都需要寫一份對應的代碼,那在維護的時候就非常麻煩,很可能會出現對社區版的修改了,而對專業版的沒改。但是有了條件編譯,廠商從始至終隻需要維護一份代碼即可,對於社區版隻要對專業版的代碼進行條件編譯,裁剪掉相應的功能即可。

編譯

在VS中,編譯器會檢查語法是否有錯誤,如果沒有錯誤,才會編譯成匯編語言。Linux下的gcc/g 也是一樣。

指令: gcc -S test.i -o test.s

生成二進制文件

匯編

匯編是生成機器可識別的代碼,匯編階段是把編譯階段生成的“.s”文件轉成目標文件

指令:gcc -c test.s -o test.o

鏈接

鏈接是指生成可執行文件或庫文件

在成功編譯之後,就進入了鏈接階段。 指令: gcc hello.o –o hello

粉絲福利, 免費領取C/C 開發學習資料包、技術視頻/項目代碼,1000道大廠面試題,內容包括(C 基礎,網絡編程,數據庫,中間件,後端開發,音視頻開發,Qt開發,遊戲開發,Linux內核等進階學習資料和最佳學習路線)↓↓↓↓有需要的朋友可以進企鵝裙927239107領取哦~↓↓

函數庫

C程序中,並沒有定義“printf”的函數實現,且在預編譯中包含的“stdio.h”中也隻有該函數的聲明,而沒有定義函數的實現,那麼,是在哪裡實“printf”函數的呢?

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

靜態庫

靜態庫是指編譯鏈接時,把庫文件的代碼全部加入到可執行文件中,因此生成的文件比較大,但在運行時也就不再需要庫文件了。其後綴名一般為“.a”

動態庫

動態庫與之相反,在編譯鏈接時並沒有把庫文件的代碼加入到可執行文件中,而是在程序執行時由運行時鏈接文件加載庫,這樣可以節省系統的開銷。動態庫一般後綴名為“.so”,如前面所述的 libc.so.6 就是動態庫。gcc 在編譯時默認使用動態庫。完成了鏈接之後,gcc 就可以生成可執行文件,gcc hello.o –o hello

gcc默認生成的二進制程序,是動態鏈接的,這點可以通過 file 命令驗證。

gcc選項

-E 隻激活預處理,這個不生成文件,你需要把它重定向到一個輸出文件裡面

-S 編譯到匯編語言不進行匯編和鏈接

-c 編譯到目標代碼

-o 文件輸出到 文件

-static 此選項對生成的文件采用靜態鏈接

-g 生成調試信息。GNU 調試器可利用該信息。

-shared 此選項將盡量使用動態庫,所以生成文件比較小,但是需要系統由動態庫.

-O0

-O1

-O2

-O3 編譯器的優化選項的4個級別,-O0表示沒有優化,-O1為缺省值,-O3優化級別最高

-w 不生成任何警告信息。

-Wall 生成所有警告信息。