有時我們需要將一組代碼編成一個庫,從而方便其複用。例如,我們調用的STL和系統函數都是以這種方式提供的。另外,當項目工程較大時,為了使其模組化方便分工,有時也需要將其建立自己的連結庫。
連結庫按照其連結方式可以分為動態連結程式庫和靜態連結庫兩種,本文主要介紹一下靜態連結庫的建立方式。
以一個簡單的代碼為例,這裡有兩個檔案main.c和stack.c,這裡打算把stack.c作為一個lib供main.c調用。
/* stack.c */
char stack[512];
int top = -1;
char pop(void)
{
return stack[top--];
}
void push(char
c)
{
stack[++top] = c;
}
/* main.c */
#include
<stdio.h>
char pop();
void push(char c);
void main(void)
{
push('a');
push('b');
printf("%c\n", pop());
}
要把stack.c編成lib,需要經過如下兩個步驟:
- 通過gcc –c命令將stack.c編成stack.o
- 通過ar命令將stack.o封裝成libstack.a
gcc -c stack.c
ar cr libstack.a stack.o
執行完這兩條命令後,就可以產生一個libstack.a的檔案了,然後再連結的時候直接使用這個.a檔案即可以產生執行檔案。
gcc -o run main.c -L. -lstack
這個連結命令並沒有什麼太多可介紹的,其中-L、-l參數用於指定連結庫,在上一篇文章中已經介紹過,這裡就不做更多說明了。
上述過程中,用到了條之前沒見過的命令ar。ar是archive的縮寫,也就是歸檔的意思,平時我們用得更多的是另一條歸檔命令tar。ar和tar的功能其實比較類似,但ar命令做了一些額外的處理,它會為被歸檔的目標檔案中的符號建立索引,當和應用程式連結時,建立的這些索引將回收連結過程
ar命令的參數比較多,如果只是建立lib庫的話,通常只用到了cr這兩個組合參數。該命令是可以接受多個輸入檔案,統一合并到一個庫中。
ar cr libtest.a first.o second.o third.o
在通過ar建立lib後,可以通過ar -t命令查看該lib裡打包了那些.o檔案
tianfang > ar -t libstack.a
stack.o
此外,還可以通過nm命令來查看符號表等更多資訊
tianfang > nm libstack.a
stack.o:
00000000 T pop
0000001b T push
00000200 C stack
00000000 D top
ar和nm的命令參數比較多,更多資訊可以參考這篇文章:AR和NM命令的使用
最後,知道了ar只是一個打包的功能後,再回頭來看看靜態連結的過程,它其實只是把一堆.o檔案打包成了一個.a檔案,連結的時候仍然是從.a檔案裡面尋找.o檔案進行連結,和之前的編譯方式並沒有什麼本質的區別。