程式的編譯和連結原理分析

chenwr2018發表於2019-03-03

程式的編譯和連結原理分析
記錄下學習《跟我一起寫makefile》這本書時整理的筆記。

一、原理說明

UNIX 下是 .o 檔案,即 Object File,這個動作叫做編譯(compile)。然後再把大量Object File 合成執行檔案,這個動作叫作連結(link)。

一般來說,每個原始檔都應該對應於一箇中間目標檔案(O 檔案或是 OBJ 檔案)。連結時,主要是連結函式和全域性變數,所以,我們可以使用這些中間目標檔案(O 檔案或是OBJ檔案)來連結我們的應用程式。連結器並不管函式所在的原始檔,只管函式的中間目標檔案(Object File)。

我們要給中間目標檔案打個包,在 Windows 下這種包叫“庫檔案”(Library File),也就是.lib 檔案,在 UNIX下,是 Archive File,也就是 .a 檔案。

總結一下,原始檔首先會生成中間目標檔案,再由中間目標檔案生成執行檔案。在編譯時,編譯器只檢測程式語法,和函式、變數是否被宣告。如果函式未被宣告,編譯器會給出一個警告,但可以生成 Object File。而在連結程式時,連結器會在所有的 Object File 中找尋函式的實現,如果找不到,那到就會報連結錯誤碼(Linker Error),意思說是說,連結器未能找到函式的實現。你需要指定函式的Object File。

二、簡單的編譯連結流程例項

程式的編譯和連結原理分析

  1. 產生可執行檔案a.out,中間產生main.o的目標檔案,但在連結成功後刪除。
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# gcc main.c 
a.out  hello.c  main.c
複製程式碼
  1. -c 引數意味著只編譯(compile) 產生main.o目標檔案
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# gcc -c main.c 
main.o  hello.c  main.c
複製程式碼
  1. 連結檔案,預設為a.out
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# gcc main.o
a.out
複製程式碼
  1. -o name 使連結器儲存可執行檔案為指定檔案中,name為指定檔名。
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# gcc -o main.o
gcc: fatal error: no input files
compilation terminated.
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# gcc main.o -o run
hello.c  main.c  main.o  Makefile  run
複製程式碼
  1. 可以結合起來使用
gcc main.c -o run
複製程式碼

編譯main.c並連結生成可執行檔案run,並將中間產生的目標檔案main.o刪除。

三、目標檔案打包與連結

使用ar命令將目標檔案打包,不過一般這個動作都是在makefile中實現。 連結靜態庫引數說明,-L 表示靜態庫路徑,-lmy 即連結libmy.a檔案

root@chenwr-pc:/home/workspace/my_workspace/study/makefile# cat main.c 
#include <stdio.h>
void main()
{
	printf("Im a super man\n");
	hello();
	test();
}
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# ar rcs libmy.a test.o hello.o
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# gcc main.c -L . -lmy -o run
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# ./run
Im a super man
hello world
test
複製程式碼

參考資料:

linux ar 命令的使用說明和例項講解_linux shell_指令碼之家 https://www.jb51.net/article/95627.htm

gcc 連結檔案 - NeverWA的部落格 - CSDN部落格 https://blog.csdn.net/NeverWA/article/details/79948049

相關文章