一、過程:預處理編譯、彙編、鏈結。
1、預處理
gcc -e filename.c (對應的後台工具為cpp)
預處理是c語言程式從源**變成可執行程式的第一步,主要是c語言編譯器對各種預處理命令進行處理,包括標頭檔案的包含、巨集定義的擴充套件、條件編譯的選擇等。
cpp:the c preprocessor,主要用來預處理巨集定義、檔案包含、條件編譯等。
2、編譯
gcc -s filename.c (對應的後台工具則分別為cc1) =>得到彙編** .s
2.1、解釋程式
將源語言書寫的源程式作為輸入,解釋一句後就提交計算機執行一句,並不形成目標程式,適合於通過終端裝置與計算機會話,適合於小型機的計算問題。解釋程式執行速度慢,易造成浪費。
2.2、編譯程式
把高階語言源程式作為輸入,進行翻譯轉換,產生出機器語言的目標程式,執行目標程式,得到計算結果。
1)分析,是指詞法分析和語法分析;
2)綜合,**優化,儲存分配和**生成。
編譯程式採用對源程式進行多次掃瞄的辦法,每次掃瞄集中完成一項或幾項任務。如詞法分析;語法分析;掃瞄做**優化和儲存分配;**生成。 對於需要經常使用的有大量計算的大型題目,採用招待速度較快的編譯型的高階語言,雖編譯過程本身較複雜,但一旦形成目標檔案,可多次使用。
3、彙編
gcc的-c選項或 as命令 (對應的後台工具為as) => 目標** .o
把作為中間結果的彙編**翻譯成了機器**(目標**)
elf格式的目標**
1)結構:
elf header(檔案頭)
porgram headers table(用於描述可執行檔案和可共享庫)
section 1
section 2
section 3
。。。。
2)相關工具
binutils(gnu binary utilities)的很多任務具都採用bfd庫來操作目標檔案,如objdump,objcopy,nm,strip等;
分析工具readelf:-h,-l和-s引數檢視elf header、program headers table段表和section headers table節區表。
4、鏈結
gcc -o filename 根據目標**連線產生可執行檔案。
處理可重定位檔案,把符號引用和符號定義轉換為可執行檔案中的資訊(一般是虛擬記憶體位址)的過程。
鏈結分為
靜態鏈結和
系統呼叫動態鏈
接器(ld-linux.so)自動鏈結。
ps:三種型別的檔案:可重定位檔案、靜態連線庫和動態連線庫。
可重定位檔案本身不可以執行,僅作為可執行檔案、靜態連線庫(也是可重定位檔案)、動態連線庫的 「元件」。
靜態連線庫和動態連線庫本身也不可以執行,作為可執行檔案的「元件」。靜態連線庫是可重定位檔案(可能是多個可重定位檔案的集合),在連線時加入到可執行檔案中去;動態連線庫在連線時,庫檔案本身並沒有新增到可執行檔案中,只是在可執行檔案中加入了該庫的名字等資訊,以便在可執行檔案執行過程中引用庫中的函式時由動態聯結器去查詢相關函式的位址,並呼叫它們。
動態共享庫的搜素順序:
1、ld_library_path
2、ldconfig utility 維護的/etc/ld.so.cache,ldconfig utility:建立、儲存共享庫。
3、/lib
4、/usr/lib
命令:idconfig -v:列出並連線共享庫;
ldd /目錄 顯示依賴關係;
objdump -i列出目標檔案、靜態庫、共享庫的摘要資訊
對一test.c 檔案的執行過程:
1、gcc test.c -o test
2、./test
gcc編譯流程
可以利用gcc的引數來控制執行的過程,這樣就可以更深入的了解編譯c程式的過程。下面將通過對乙個程式的編譯來演示整個過程。includeint main 1 預處理 編譯器將c程式的標頭檔案編譯進來,還有巨集的替換,可以用gcc的引數 e來參看。命令 gcc e hello.c o hello.i 作...
gcc編譯流程
步驟命令 說明預處理 gcc e hello.c o hello.i 1.將所有 define刪除,並且展開所有的巨集定義 2.處理所有的條件預編譯指令,如 if ifdef undef ifndef endif elif 3.處理 include,將包含的檔案插入到此處,這是乙個遞迴的過程 4.刪...
GCC編譯流程
gcc使用的基本語法為 gcc option filename 這裡option是gcc使用時的一些選項,可以通過指定不同的選項實現不同的功能。這裡的filename是gcc要編譯的檔案,gcc會根據使用者指定的編譯選項以及所識別的檔案字尾名來對編譯檔案進行響應的處理。1,預處理階段 預處理功能分為...