01 gcc的編譯過程

2021-10-02 16:44:35 字數 2286 閱讀 8211

前言

如果我們學習過c語言,肯定寫過 hello world這個最簡單的程式。但是從原始檔到可執行程式,中間都經歷了哪些過程呢?下面我們就開始研究一下。

環境搭建

系統:ubuntu 16.04.1 lts

編譯器:gcc

hello.c源程式

#include

//這個乙個注釋

intmain

(void

)

預處理

用gcc來編譯hello.c時,首先是要通過預處理器來處理原始檔,我們開始實操,看看預處理到底做了什麼?

python@ubuntu:~/code$ gcc -e hello.c -o hello.i

python@ubuntu:~/code$ ll hello.i

-rw-rw-r-- 1 python python 17119 6月 26 23:53 hello.i

我們vi hello.i,然後shift+g來到檔案末尾,此時我們看到它去掉了原始檔中的注釋。

我們接著查詢一下printf函式

這下我們就明白了,它把stdio.h標頭檔案的內容複製到了這裡面來,也就是說執行了預處理指令(例如#include #define等等)。編譯

預處理做完以後,此時可以把hello.i編譯成hello.s這個彙編檔案。

python@ubuntu:~/code$ gcc -s hello.i -o hello.s

python@ubuntu:~/code$ cat hello.s

.file "hello.c"

.section .rodata

.lc0:

.string "hello litelefishc"

.text

.globl main

.type main, @function

main:

.lfb0:

.cfi_startproc

pushq %rbp

.cfi_def_cfa_offset 16

.cfi_offset 6, -16

movq %rsp, %rbp

.cfi_def_cfa_register 6

movl $.lc0, %edi

call puts

movl $0, %eax

popq %rbp

.cfi_def_cfa 7, 8

ret.cfi_endproc

.lfe0:

.size main, .-main

.ident "gcc: (ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609"

.section .note.gnu-stack,"",@progbits

彙編

編譯完成以後就可以將組合語言檔案匯編成目標檔案

python@ubuntu:~/code$ gcc -c hello.s 

python@ubuntu:~/code$ ls

hello.c hello.i hello.o hello.s

這裡可以使用二進位制工具檢視一下這個目標檔案,在linux系統一般是elf檔案結構。鏈結

最後將生成目標檔案,系統庫的目標檔案,庫檔案進行鏈結,生成乙個可執行程式。

python@ubuntu:

~/code$ gcc hello.o

python@ubuntu:

~/code$ .

/a.out

hello litelefishc

gcc常用選項

-i:包含的標頭檔案的路徑

-l:包含庫檔案的路徑

-l:指定庫名lib***.so

-o:優化選項,1~3越高優先順序越高

-w:警告,all顯示更多的

-c:編譯成.o檔案

-e:輸出到標準輸出,巨集替換,標頭檔案展開

-s:編譯成彙編

-lstdc++:編譯c++**

-o:目標檔案

-g:用於gdb除錯,不加此選項不能用於gdb除錯

總結

gcc編譯過程

本文對gcc編譯器如何工作做乙個概要描述.更為詳細的資訊請參考編譯器手冊。當我們進行編譯的時候,要使用一系列的工具,我們稱之為工具鏈.其中包括 預處理器cpp,編譯器前端gcc g 彙編器as,聯結器ld.乙個編譯過程包括下面幾個階段 1 預處理。預處理器cpp將對原始檔中的巨集進行展開。2 編譯。...

gcc編譯過程

當我們進行編譯的時候,要使用一系列的工具,我們稱之為工具鏈.其中包括 預處理器cpp,編譯器前端gcc g 彙編器as,聯結器ld.乙個編譯過程包括下面幾個階段 1 預處理。預處理器cpp將對原始檔中的巨集進行展開。2 編譯。gcc將c檔案編譯成彙編檔案。3 彙編。as將彙編檔案編譯成機器碼。4 連...

GCC編譯過程

第一步 預處理後結束 引數 e gcc e hello.c o hello.i 檢視hello.i檔案中的內容 cat hello.i stdio.h的內容插入到檔案裡去了,巨集定義也在預處理中都做了相應的處理 第二步 將hello.i 編譯為 目標 引數 c gcc c hello.i o hel...