1. 程式人生 > >Linxu之靜態庫生成和使用

Linxu之靜態庫生成和使用

Linux下靜態庫生成和使用

一.靜態庫概念

1.庫是預編譯的目標檔案(object  files)的集合,它們可以被連結程序序。靜態庫以後綴為”.a”的特殊的存檔(archive file)儲存。

2.標準系統庫可在目錄/usr/lib與/lib中找到。比如,在類Unix系統中C語言的數序庫一般儲存為檔案/usr/lib/libm.a。該庫中函式的原型宣告在標頭檔案/usr/include/math.h中。

3.C標準庫本身儲存為/usr/lib/libc.a,它包含ANS1/ISO標準指定的函式,比如printf。對每一個C程式來說,libc.a都預設被連結。

 4.一個事例:

在程式中呼叫一個數序庫libm.a中sin函式。

#include<stdio.h>

#include<math.h>

int  main()

{

         double  x = 2.0;

         double y = sin(x);

         printf(“the result:%f\n”,y);

         return 0;

}

如果直接使用gcc tiger.c則會出現錯誤:

undefined  reference to ‘sin’;

1>函式sin(),未在本程式中定義也不在預設庫’libc.a’中,除非被指定,編譯器也不會連結’libm.a’。

2>為使編譯器能將sin()連結進主程式‘test.c’,需要提供數學庫’libm.a’.。

3>使用方法:

gcc  tiger.c /usr/lib/libm.a  -o tiger

則可以編譯通過。為了避免在命令列中指定長的路徑,編譯器為連結函式庫提供了快捷的選項’-l’。因此可以使用下面的方法:

gcc  tiger.c -lm –o tiger

注:選項-lNAME使用聯結器嘗試連結系統庫目錄中的函式庫檔案libNAME.a。

二.生成和使用靜態庫

1.靜態庫是obj檔案的一個集合,通常靜態庫以”.a”為字尾。靜態庫由程式ar生成。

2.靜態庫的優點是可以在不用重新編譯程式庫程式碼的情況下,進行程式的重新連結,這種方法節省了編譯過程的時間(在編譯大型程式的時候,需要花費很長的時間)。靜態庫的另一個優點是開發者可以提供庫檔案給使用的人員,不用開放原始碼,這是庫函式提供者經常採用的手段。

3.通過一個例項來了解如何自己生成靜態庫和使用靜態庫

首先生成靜態庫

1>在test資料夾下有三個檔案:main.c ,tiger.c,tiger.h;

a. main.c檔案中的內容:

#include<stdio.h>

#include”tiger.h”

int  main(void)

{

       printf(“sum=%d\n”,add(3,5));

       return 0;      

}

b.tiger.h檔案中的內容:

#ifndef __TIGER__

#define __TIGER__

int  add(int  a,int b);

#endif

c.tiger.c檔案中的內容

int  add(int  a,int b)

{

        return a+b;

}

2>建立靜態庫的最基本步驟是生成目標檔案tiger.o

gcc  -o tiger.o  -c  tiger.c

3>然後生成靜態庫libadd.a:

ar  -rcs libadd.a  tiger.o    

其次使用靜態庫

1>使用gcc命令帶上庫檔案就OK了

   gcc  -o  main main.c  libadd.a

2> 也可以使用命令”-l庫名”進行,庫名是不包含庫函式庫和副檔名的字串。

   gcc  -o  main  main.c -ladd

上面的命令執行完後,系統返回:

Cannot  find –ladd

說明:上面的命令將在系統預設的路徑西安查詢add函式庫,並把他連結到要生成的目標程式上。系統提示沒有找到庫檔案add,這是由於add庫函式沒有在系統預設的查詢路徑下,我們需要認為指定庫函式的路徑,例如:庫檔案和當前編譯檔案在同一目錄下:
   gcc  -o main  main.c -L  ./  -ladd

系統就能正常生成可執行檔案。

說明:

       在使用-l選項時,-o選項的目的名要在-l連結的庫名之前,否則gcc會認為-l是生成的目標而出錯。