一、原理說明
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。
二、簡單的編譯連結流程例項
- 產生可執行檔案a.out,中間產生main.o的目標檔案,但在連結成功後刪除。
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# gcc main.c
a.out hello.c main.c
複製程式碼
- -c 引數意味著只編譯(compile) 產生main.o目標檔案
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# gcc -c main.c
main.o hello.c main.c
複製程式碼
- 連結檔案,預設為a.out
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# gcc main.o
a.out
複製程式碼
- -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
複製程式碼
- 可以結合起來使用
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