C程式的編譯鏈結過程

2021-07-30 16:43:37 字數 2725 閱讀 6071

程式由原始檔編譯得到可執行檔案看起來好像是很簡單的過程,windows的ide環境下,點一下bulid就可以生成可執行檔案,在linux環境下,gcc編譯器也提供了很多選項可以很方便的從原始檔生成可執行檔案。事實上程式的編譯和鏈結是乙個非常複雜的過程,ide幫我們隱藏了大量的細節。下面我們以最經典的hello,world程式來分析一下,從源程式到生成可執行檔案都發生了哪些事情。

檔案內容

#includeint main()

##1. 預處理

預處理的主要作用有三個:

處理原始檔**中以」#」開頭的那些**,比如#include,#define等。將所有的巨集定義全部展開。

處理條件編譯

刪除所有注釋

通過gcc的-e選項來預處理main.c檔案。

檢視一下生成的main.i的檔案內容,可以看到stdio.h檔案內的內容已經全部被插入到檔案當中了,同時所有的巨集定義也被展開(main.i檔案很長,擷取的是一部分)。在檔案的最後是我們main函式的**。

#2. 編譯

編譯就是將預處理得到的*.i檔案生成彙編**檔案(.s檔案)。注意:通常所說的編譯是指程式從源**到生成可執行檔案的全過程,在這裡指的由.i檔案生成*.s檔案的過程。輸入下面的命令來實現編譯過程,得到main.s檔案。

gcc –s main.i –o main.s#3. 彙編

彙編就是將彙編**變成機器碼。每一條彙編語句幾乎都對應了一條機器碼。所以這一步驟非常簡單,根據彙編指令和機器指令對照表一對一翻譯就ok。輸入下面的指令實現這一過程。

gcc –c main.s –o main.o

此時,main.o檔案已經生成,這個時候main.o已經是乙個二進位制檔案,不能用cat檢視,用hexdump來看一下main.o檔案內容。

生成main.out可執行檔案。

以上就是從原始檔到可執行檔案的全部過程。這是乙個很簡單的範例,在main.c檔案中僅包含了標準標頭檔案,沒有包含自定義的標頭檔案。下面介紹乙個簡單的例子。

首先準備三個檔案

檔案內容

#include#include "fun.h"

int main()

檔案內容

#ifndef fun_h

#define fun_h

int calc(int a,int b);

#endif

檔案內容

#include"fun.h"

int calc(int a,int b)

在main.c檔案中包含了fun.h檔案,並呼叫了fun.h中定義的calc函式,calc函式的實現在calc.c檔案中。

#1.預處理、編譯、彙編main.c檔案

此時main.o檔案是不能生成可執行檔案的。

編譯器提示undefined reference to `calc』,因為我們沒有鏈結庫檔案。

#2.建立靜態庫檔案

1.首先,編譯fun.c得到fun.o目標檔案

2.然後,建立靜態庫檔案

3.在某些系統中,還要為靜態庫生成乙個內容表

ranlib libfun.a

4.庫檔案建立完成後,就可以鏈結了。

#3.程式鏈結靜態庫檔案

前面已經生成了main.o文和libfun.a檔案,現在我們鏈結一下,生成可執行檔案。

gcc main.o -o main.out -l. -l fun

注意一下這條語句的規則,-l表示指定庫檔案目錄,」.」表示當前資料夾,這裡也可以寫出目錄完整路徑。-l fun表示指定庫檔名,庫檔案的完整名是libfun.a,前面的lib和字尾.a均省略。

可見,main.out檔案已經生成,可以執行

程式編譯,鏈結過程

c語言的編譯鏈結過程要把我們編寫的乙個c程式 源 轉換成可以在硬體上執行的程式 可執行 需要進行編譯和鏈結。編譯就是把文字形式源 翻譯為機器語言形式的目標檔案的過程。鏈結是把目標檔案 作業系統的啟動 和用到的庫檔案進行組織形成最終生成可載入 可執行 的過程。過程 如下 預處理器 將.c 檔案轉化成 ...

程式的編譯鏈結過程

一段源 到可執行性程式需要經歷預處理 編譯彙編和鏈結等步驟,接下來詳細介紹這些過程 假設檔案main.czhong有如下 include int main 1 巨集定義指令 2 條件編譯 3 標頭檔案包含指令 4 特殊符號處理 不能在標頭檔案中定義全域性變數,因為在標頭檔案中定義全域性變數將會使所有...

c 編譯鏈結過程

llinux下編譯乙個c 程式的典型過程 1.編譯預處理 預編譯程式完成的工作,可以說成是對源程式的 替換 工作。經過這個過程,生成乙個沒有巨集定義 沒有條件編譯指令 沒有特殊符號的輸出檔案。2.編譯 優化階段 通過詞法分析 語法分析,在確認所有的指令都符合語法規則之後,將其翻譯成等價的中間 或彙編...