Linux系統C語言編譯

Table of Contents

 

gcc

gcc編譯流程:

總體參數

gcc的常用警告和出錯參數 

優化參數

gdb

常用的gdb命令

用gdb調試程序


知識簡介

編譯  :把高級語言書寫的代碼轉換爲機器可識別的機器指令。編譯高級語言後生成的指令雖然可被機器識別,但是還不能被執行。編譯時,編譯器檢查高級語言的語法、函數與變量的聲明是否正確。只有所有的語法正確、相關變量定義正確編譯器就可以編譯出中間目標文件。通常,一個高級語言的源文件都可對應一個目標文件。目標文件在Linux 中默認後綴爲“.o”(如“foo.c”的目標文件爲“foo.o”)。

鏈接  :將多.o 文件,或者.o 文件和庫文件鏈接成爲可被操作系統執行的可執行程序(Linux 環境下,可執行文件的格式爲“ELF”格式)。鏈接器不檢查函數所在的源文件,只檢查所有.o 文件中的定義的符號。將.o 文件中使用的函數和其它.o 或者庫文件中的相關符號進行合併,對所有文件中的符號進行重新安排(重定位),並鏈接系統相關文件(程序啓動文件等)最終生成可執行程序。鏈接過程使用 GNU 的“ld”工具。

靜態庫  :又稱爲文檔文件(Archive File)。它是多個.o 文件的集合。Linux 中靜態庫文件的後綴爲“.a”。靜態庫中的各個成員(.o 文件)沒有特殊的存在格式,僅僅是一個.o 文件的集合。使用“ar”工具維護和管理靜態庫。

共享庫  :也是多個.o 文件的集合,但是這些.o 文件時有編譯器按照一種特殊的方式生成(Linux 中,共享庫文件格式通常爲“ELF”格式。共享庫已經具備了可執行條件)。模塊中各個成員的地址(變量引用和函數調用)都是相對地址。使用此共享庫的程序在運行時,共享庫被動態加載到內存並和主程序在內存中進行連接。多個可執行程序可共享庫文件的代碼段(多個程序可以共享的使用庫中的某一個模塊,共享代碼,不共享數據)。另外共享庫的成員對象可被執行(由 libdl.so 提供支持)。

gcc

Linux下的c編譯器中,gcc是功能最強大、使用最廣泛的軟件。

gcc是(GNU Cmpiler Collection的簡稱),它是GNU項目中符合ANSI C標準的編譯系統,能夠編譯用C、C++和Object C等語言編寫的程序。

gcc不僅功能十分強大,結構也異常靈活。它可以通過不同的前端模塊來支持各種語言,如Java、Fortran、Pascal、Modula-3和Ada等。

gcc是可以在多種硬體平臺上編譯出可執行程序的超級編譯器,其執行效率與一般的編譯器相比,平均效率要高20%~30%。

gcc支持編譯的後綴名:

後綴名 對應語言 後綴名 對應語言
.c C原始程序 .ii 已經經過預處理的C++原始程序
.C C++原始程序 .s 彙編語言原始程序
.cc C++原始程序 .S 彙編語言原始程序
.cxx C++原始程序 .h 預處理文件(頭文件)
.m Objective-C原始程序 .o 目標文件
.i 已經經過預處理的c原始程序 .a/.so 編譯後的庫文件

 


gcc指令的一般格式爲:
gcc [參數] 要編譯的文件 [參數] [目標文件]

gcc 1-2.c -o 1-2

gcc編譯流程:

 

  • 編輯源碼程序代碼
  • 預處理階段:
    gcc 1-3.c -o 1-3.i -E

     

 

  • 編譯階段:
    gcc 1-3.i -o 1-3.s -S

     

  • 彙編階段
    gcc 1-3.s -o 1-3.o -c

     

  • 鏈接階段:完成鏈接後,gcc就可以生成可執行程序文件 

注意:gcc在編譯的時候默認使用動態鏈接庫,編譯鏈接時並不把庫文件的代碼加入到可執行文件中,而是在程序執行的時候動態加載鏈接庫,這樣可以節省系統開銷。


總體參數

參數 含義 參數 含義
-c

只是編譯不鏈接

-v 顯示gcc的版本信息
-S 只是編譯不彙編,生成彙編代碼 -I dir 在頭文件的搜索路徑中添加dir目錄
-E 只進行預編譯 -L dir 在庫文件的搜索路徑列表中添加dir目錄
-g 在可執行程序中包含調試信息 -static 鏈接靜態庫
-o file 把輸出文件輸出到file中 -l libra 連接名爲library的庫文件

當頭文件與gcc不在同一目錄下要用-I dir編譯,它是指頭文件,而添加庫文件時需用-L dir參數。

Linux下的庫文件命名時有一個規定:必須以l、i、b三個字母開頭,因此,在用“-l”指定鏈接庫文件時可以省去l、i、b三個字母。也就是說“-llibsunq”有時候寫成“-lsunq”。  


gcc的常用警告和出錯參數 

參數 含義
-ansi 支持符合ANSI的c程序
-pedantic 允許發出ANSI c標準所列的全部警告信息
-pendantic-error 允許發出ANSI c標準所列的全部錯誤信息
-w 關閉所有警告
-Wall 允許發出gcc提供的所有有用的告警信息
-werror 把所有的告警信息轉化爲錯誤信息,並在告警發生時終止編譯
步驟 2:關閉所有告警
gcc  1-7.c  –o  1-7  –w
步驟 3:顯示不符合ANSI c標準語法的告警信息
gcc  1-7.c  –o  1-7  –ansi
步驟 4: 允許發出ANSI c標準所列的全部警告信息
gcc  1-7.c  –o  1-7  –pedantic
步驟 5:允許發出gcc提供的所有有用的告警信息
gcc  1-7.c  –o  1-7  –Wall

優化參數

代碼優化指的是編譯器通過分析源代碼,找出其中尚未達到最優的部分,然後對其重新進行組合,目的是改善程序的執行性能。

gcc提供的代碼優化功能非常強大,它通過編譯參數“-On”來控制優化代碼的生成,其中n是一個代表優化級別的整數。

通常來說,數字越大優化的等級越高,同時也就意味着程序的運行速度越快。

gcc  1-8.c  –o  1-8  –O2

優化雖然能夠給程序帶來更好的執行性能,但在一些場合中應該避免優化代碼。 

  • 程序開發的時候。 
  • 資源受限的時候。 
  • 跟蹤調試的時候。

gdb

Linux下的gdb調試器,是一款GNU組織開發併發布的UNIX/Linux下的程序調試工具。它沒有圖形化的友好界面,但功能強大。
在進行應用程序的調試之前,要注意的是gdb進行調試的是可執行文件,而不是如“.c”這樣的源代碼文件。因此,需要先通過gcc編譯生成可執行文件才能用gdb進行調試。

gcc 1-9.c  –o  1-9 –g
gdb  1-9

常用的gdb命令

命令格式 作用
list<行號>|<函數名> 查看指定位置的程序源代碼
break 行號|函數名<條件表達式> 設置斷點
info break 顯示斷點信息
run  運行程序
print 表達式|變量 查看程序運行時對應表達式和變量的值
next 單步恢復程序運行,但不進入函數調用
step 單步恢復程序運行,且進入函數調用
continue 繼續執行函數,直到函數結束或遇到新的斷點

用gdb調試程序

  • 查看源文件

在gdb中輸入“l”(list)就可以查看程序源代碼,一次顯示10行; 

  • 設置斷點

在gdb中設置斷點命令是“b”(break),後面跟行號或者函數名。
如:(gdb) b 10   

  • 查看斷點信息

用命令“info b”(info break)查看斷點信息。

注意:gdb在一個程序中可以設置多個斷點,有多個斷點中斷時,“Num”處顯示斷點序號。

  • 運行程序:輸入“r”(run)開始運行程序。

注意:gdb默認從第一行開始運行,如果要從程序中指定行開始運行,只需輸入“r”+行號。

  • 查看變量值

程序運行到斷點處會自動暫停,輸入“p 變量名”.

調試程序時,可能需要修改變量值,程序運行到斷點處時,輸入“set 變量=設定值”,例如給變量“a2” 賦值11,輸入“set a2=11”。

gdb在顯示變量值時都會在對應值前加“$n”標記,它是當前變量值的引用標記,以後想再引用此變量,可以直接使用“$n”,提高了調試效率 

注意:查看變量值,不能在程序結束後。

  • 單步運行

在斷點處輸入 “n”(next)或者“s”(step) 。它們之間的區別在於:若有函數調用時,“s”會進入該函數而“n”不會進入該函數。

 

  • 繼續運行程序

輸入“c”(continue)命令恢復程序的正常運行,把剩餘的程序執行完,並顯示執行結果。

  • 退出gdb環境:輸入“q”(quit)命令。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章