Gcc編譯器可以將C和C++語言的源程序、匯編程序和目標程序編譯連接成可執行文件。如果不給出可執行文件的名稱,gcc會生成壹個名為a.out的文件,在Linux系統中,可執行文件沒有統壹的後綴,系統根據屬性區分可執行文件和不可執行文件。而gcc通過後綴來區分輸入文件的類別。下面介紹壹些gcc遵循的約定規則。
。C為後綴文件,C語言源代碼文件;
帶有的文件。後綴是由目標文件組成的歸檔文件;
後綴為的文件。c,。抄送或者。cxx是C++源代碼文件;
包含的文件。h後綴是程序中包含的頭文件;
包含的文件。I後綴是經過預處理的C源代碼文件;
包含的文件。ii後綴是經過預處理的C++源代碼文件;
包含的文件。m後綴是壹個Objective-C源代碼文件;
包含的文件。o後綴是編譯後的目標文件;
壹個文件。s後綴是壹個匯編語言源代碼文件;
帶有後綴的文件。s是預編譯的匯編語言源代碼文件。
Gcc的實施過程
雖然我們稱gcc為C語言的編譯器,但是使用Gcc從C語言的源代碼文件生成可執行文件的過程不僅僅是壹個編譯過程,還涉及到預處理、編譯、匯編、鏈接四個相互關聯的步驟。
命令gcc首先調用cpp進行預處理。在預處理過程中,文件包含和預編譯語句(如宏定義等。)在源代碼文件中進行分析。然後調用cc1進行編譯。在這個階段,帶有。o後綴是根據輸入文件生成的。匯編過程是指匯編語言的步驟,調用as來工作。壹般來說,匯編語言的源代碼文件用。後綴的匯編語言文件。後綴都生成目標文件。預編譯和匯編後的o後綴。當所有的目標文件生成後,gcc調用ld完成最後的關鍵工作,這個階段就是連接。在連接階段,所有的目標文件都被排列在可執行程序中適當的位置,同時程序調用的庫函數也從各自的檔案中連接到適當的地方。
Gcc的基本用法和選項
使用Gcc編譯器時,必須給出壹系列必要的調用參數和文件名。Gcc編譯器的調用參數有100多個,大部分可能根本用不到。這裏只介紹最基本最常用的參數。
Gcc最基本的用法是:∶Gcc[選項][文件名]]。
其中,options是編譯器需要的參數,filenames給出了相關的文件名。
-c,只編譯,不鏈接成為可執行文件。編譯器只生成帶有後綴的目標文件。o從輸入的源代碼文件如。c,通常用於編譯不包含主程序的子程序文件。
-o output_filename,確保輸出文件的名稱是output_filename,並且此名稱不能與源文件同名。如果沒有給出這個選項,gcc會給出預置的可執行文件a.out。
-g,生成符號調試工具(GNU的gdb)所必需的符號信息。如果我們想調試源代碼,我們必須添加這個選項。
-O,優化程序的編譯和鏈接。使用該選項,在編譯和鏈接的過程中會對整個源代碼進行優化,這樣可以提高生成的可執行文件的執行效率,但編譯和鏈接的速度相應較慢。
-O2在優化編譯連接方面比-O好,當然整個編譯連接過程會慢壹些。
-Idirname將dirname指示的目錄添加到程序頭文件的目錄列表中,是預編譯期間使用的參數。C程序中的頭文件包含兩種情況:
a)#包括
b)#包含“myinc.h”
其中,A類使用尖括號(
-Ldirname將dirname指示的目錄添加到程序函數存檔文件的目錄列表中,是連接過程中使用的參數。默認狀態下,鏈接器ld在系統的默認路徑(如/usr/lib)中搜索所需的存檔文件。該選項告訴鏈接器首先在-L指定的目錄中搜索,然後在系統的默認路徑中搜索。如果函數庫存儲在多個目錄中,則需要依次使用該選項給出相應的存儲目錄。
-lname,連接時加載名為“libname.a”的函數庫,該函數庫位於系統預置目錄或-L選項確定的目錄下。比如,-lm的意思是連接壹個名為“libm.a”的數學函數庫。
以上,我們簡單介紹了gcc編譯器最常用的函數和主要參數選項。更多詳細信息,請參考Linux系統的在線幫助。
假設我們有壹個名為test.c的C語言源代碼文件,生成可執行文件最簡單的方法是:
gcc測試
此時預編譯和編譯連接壹次性完成,由系統預置生成壹個名為a.out的可執行文件。對於稍微復雜壹點的情況,比如有多個源代碼文件,需要連接到存檔或者有其他特殊需求,應該給出適當的調用選項參數。再看壹個簡單的例子。
整個源代碼程序由testmain.c和testsub.c兩個文件組成,其中使用了系統提供的數學庫,可執行文件預計為test。這時,編譯命令可以是:
gcc test main . c test sub c□lm□o測試
其中-lm代表連接系統的數學庫libm.a。
Gcc中的錯誤類型及對策
如果Gcc編譯器在源程序中發現錯誤,就無法繼續,無法生成最終的可執行文件。為了便於修改,gcc給出了錯誤信息。我們必須對這些錯誤信息逐壹進行分析和處理,並修改相應的語言,以確保源代碼的正確編譯和連接。gcc給出的錯誤信息壹般可以分為四類。下面分別討論壹下原因和對策。
第壹類:C類語法錯誤
錯誤信息:文件source中存在語法錯誤(syntex error)C這種類型的錯誤壹般是C語言中的語法錯誤,所以我們要仔細檢查源代碼文件中n行之前的程序,有時還需要檢查這個文件中包含的頭文件。在某些情況下,gcc會為壹個簡單的語法錯誤給出很多錯誤。我們最重要的是保持清醒的頭腦,不要被它嚇倒,必要的時候參考C語言的基礎教材。
第二類:頭文件錯誤
錯誤消息:找不到頭文件head.h(找不到包含文件head.h)。這種錯誤是源代碼文件中的頭文件有問題。可能的原因包括頭文件名稱錯誤、指定頭文件的目錄名稱錯誤等。,或者雙引號和尖括號的錯誤使用。
第三類:存檔錯誤
錯誤消息:鏈接器找不到所需的庫,例如:
ld: -lm:沒有這樣的文件或目錄
這種錯誤是連接到目標文件的函數庫中的錯誤。可能的原因是函數庫名稱錯誤和指定函數庫所在目錄名稱錯誤。檢查的方法是使用find命令在可能的目錄中查找對應的函數庫名稱,確定存檔和目錄的名稱,在程序和編譯選項中修改名稱。
類別4:未定義的符號
錯誤消息:有壹個未定義的符號。這種錯誤發生在連接過程中,可能有兩個原因:壹是用戶定義的函數或全局變量所在的源代碼文件沒有編譯、連接或根本沒有定義,需要用戶根據實際情況修改源程序,給出全局變量或函數的定義體;第二,未定義符號是壹個標準庫函數,在源程序中使用,但是在連接過程中沒有給出對應庫的名稱,或者是存檔的目錄名有問題。這時候我們需要使用存檔維護命令ar來檢查我們需要哪個庫函數,確認後再修改gcc連接選項中的-l和-L項。
在編譯連接的過程中消除錯誤,應該說這只是程序設計中最簡單最基礎的壹步,可以說只是開始。這個過程中的錯誤只是我們用C語言描述壹個算法時犯的錯誤,相對容易消除。我們編寫壹個程序,直到它被編譯和連接。應該說才剛剛開始。程序運行過程中出現的問題是算法設計的問題。更具體的說,我們對問題的認識和理解不夠,需要更深入的測試、調試和修改。壹個程序,稍微復雜壹點的程序,往往要編譯、鏈接、測試、修改很多次。下面我們學習的程序維護、調試工具、版本維護,都是在程序調試和測試的過程中使用,解決調試階段的問題。頁頭
表單底部