Linux 靜態庫生成指南

JollyWing的部落格發表於2015-03-11

Linux上的靜態庫,其實是目標檔案的歸檔檔案。

在Linux上建立靜態庫的步驟如下:

  1. 寫原始檔,通過 gcc -c xxx.c 生成目標檔案。
  2. 用 ar 歸檔目標檔案,生成靜態庫。
  3. 配合靜態庫,寫一個使用靜態庫中函式的標頭檔案。
  4. 使用靜態庫時,在原始碼中包含對應的標頭檔案,連結時記得連結自己的庫。

下面通過例項具體講解。

寫原始檔,生成目標檔案。

第一個原始檔 my_print.c

#include <stdio.h>

void cout(const char * message)
{
    fprintf(stdout, "%s\n", message);
}

原始檔2: my_math.c

int add(int a, int b)
{
    return a + b;
}

int subtract(int a, int b)
{
    return a - b;
}

使用gcc,為這兩個原始檔生成目標檔案:

gcc -c my_print.c my_math.c

我們就得到了 my_print.o 和 my_math.o。

歸檔目標檔案,得到靜態庫。

我們使用 ar 將目標檔案歸檔:

ar crv libmylib.a my_print.o my_math.o

我們就得到了libmylib.a,這就是我們需要的靜態庫。

上述命令中 crv 是 ar的命令選項:

  • c 如果需要生成新的庫檔案,不要警告
  • r 代替庫中現有的檔案或者插入新的檔案
  • v 輸出詳細資訊

通過 ar t libmylib.a 可以檢視 libmylib.a 中包含的目標檔案。

可以通過 ar --help 檢視更多幫助。

注意:我們要生成的庫的檔名必須形如 libxxx.a ,這樣我們在連結這個庫時,就可以用 -lxxx
反過來講,當我們告訴編譯器 -lxxx時,編譯器就會在指定的目錄中搜尋 libxxx.a 或是 libxxx.so

生成對應的標頭檔案

標頭檔案定義了 libmylib.a 的介面,也就是告訴使用者怎麼使用 libmylib.a。

新建my_lib.h, 寫入內容如下:

#ifndef __MY_LIB_H__
#define __MY_LIB_H__

int add(int a, int b);
int subtract(int a, int b);

void cout(const char *);
#endif

測試我們的靜態庫

在同樣的目錄下,建立 test.c:

#include "my_lib.h"

int main(int argc, char *argv[])
{
    int c = add(15, -21);
    cout("I am a func from mylib ...");
    return 0;
}

這個原始檔中引用了 libmylib.a 中的 cout 和 add 函式。

編譯test.c:

gcc test.c -L. -lmylib

將會生成a.out,通過 ./a.out 可以執行該程式。說明我們的靜態庫能正常工作。

上面的命令中 -L. 告訴 gcc 搜尋連結庫時包含當前路徑, -lmylib 告訴 gcc 生成可執行程式時要連結 libmylib.a

通過makefile自動化

上面的步驟很繁瑣,還是寫個簡單的makefile吧,內容如下:

.PHONY: build test

build: libmylib.a

libmylib.a: my_math.o my_print.o
	ar crv $@ my_math.o my_print.o

my_math.o: my_math.c
	gcc -c my_math.c

my_print.o: my_print.c
	gcc -c my_print.c

test: a.out

a.out: test.c
	gcc test.c -L. -lmylib

makefile寫好後,執行 make build 將會構建 libmylib.a, 執行 make test 將會生成連結 libmylib.a 的程式。

如果你在 windows 上使用 mingw,和Linux下生成靜態庫的方法是一樣的。

相關文章