軟件開發者可以使用某種語言的庫函數,這些庫函數通常放在/lib和/usr/lib目錄中,而大多數的庫函數放在/usr/lib中,比如標準C庫函數文件/usr/lib/libc.a和標準C++庫函數/usr/lib/libstdc++.a。
庫對應的頭文件有兩種,包括公有頭文件和私有頭文件。公有頭文件聲明的資源對其他程序是有效的,而私有頭文件聲明的資源只能被對應的庫代碼使用。為了使庫成為公有的,應將它安裝在目錄/usr/lib中,并將它的頭文件放在/usr/include中,并在用戶程序中使用#include <>的方式引入庫頭文件。將頭文件的路徑名放置在引號中,就可將私有頭文件放入程序中,比如#include "hello.h",預處理程序會首先在當前目錄查找hello.h頭文件,如果寫成#include "-/include/hello.h",預處理程序就會在目錄~/include中搜索頭文件hello.h。
庫文檔必須以.a擴展名結束,一旦為一組目標模塊創建了一個庫文件,通過制定庫文檔作為參數,這些模塊就可以被C程序根據-l*鏈接使用。對于標準庫,例如C中的libc.a,只需要在用戶程序中添加相應的頭文件比如stdio.h、stdlib.h、ctype.h等,而不需要明確地用-l編譯程序選項去鏈接該庫;但還有許多庫不是標準庫,例如數學庫libm.a,除了需要添加相應頭文件之外,還必須明確地用編譯程序選項-lm鏈接該庫,其中-l編譯選項在lib和.a之間指定子串,不明確指定的話會在編譯器產生錯誤。
注意:
1.標準C語言庫libc.a在編譯程序的鏈接階段自動被鏈接。
2.一些常見的與庫相關的編程錯誤:
沒有為庫加入頭文件
沒有明確鏈接一個庫,而這個庫不能被程序自動鏈接
使用了錯誤版本的庫
鏈接了不兼容的庫

------------------------------------------------------------------------------------------------------

庫的開發

使用ar程序可以執行各種與庫相關的任務,比如在庫文件中創建、修改和提取模塊等。與linux命令不同,ar命令的關鍵字不需要使用-連字符。
ar 關鍵字 庫文檔名 文件列表
d    在庫文檔中刪除一個文件
q    在現有庫文檔中添加一個文件,若庫文檔不存在,則創建之
r     新建一個庫文檔或覆蓋一個現有庫文檔
t     顯示一個庫文檔目錄
s    強制生成庫文檔符號表
x     從一個庫文檔中提取一個或多個文件,并將它們保存在當前的工作目錄中
v    生成一個詳細的輸出

假設已存在main.c、compute.c、input.c、main.h、compute.h、input.h這些文件,且compute.c使用了數學庫libm.a,下面的例子用于庫文檔的創建和追加等。
ar r libmath.a input.o compute.o
該命令創建了文件input.o和compute.o的庫文檔文件libmath.a,如果該庫文檔已存在則會被覆蓋。上述命令當libmath不存在時,可以使用ar q libmath.a input.o compute.o代替,該命令在libmath.a中追加新文件,當libmath.a不存在時自動創建;當想將當前目錄中所有目標文件都放入庫文件中,也可以使用ar r libmath.a *.o或者ar r libmath.a `ls *.o`這樣的命令。
gcc main.c libmath.a -o power -lm
該命令將庫文檔中的input.o和compute.o鏈接到main.o上,使用-lm鏈接數學庫libm.a,因為在compute.o中使用了pow函數。將libmath.a安裝到/usr/lib后,就可以通過-lmath的方式使用了。
rm compute.o input.o
創建目標模塊的庫文檔后,就可以刪除原有模塊。
ar t libmath.a
該命令用于顯示庫文檔libmath.a的目錄,同理可以使用ar vt libmath.a命令獲得更詳細的輸出。
ar d libmath.a input.o
該命令用于從庫文檔libmath.a中刪除一個或多個目標模塊。
ar x libmath.a compute.o
該命令下哦那個庫文檔libmath.o中提取一個或多個目標模塊,并放在當前目錄中。

在makefile中也可以使用ar命令,這樣創建了軟件的可執行文件之后,也可以創建目標文檔的庫文檔,具體方法如下:
CC=gcc
OPTIONS=-03
OBJECTS=main.o input.o compute.o
SOURCES=main.c input.c compute.c
HEADERS=main.h input.h compute.h
ARCHIVE=compute.o input.o
LIBRARY=libmath.a
AR_KEYS=qv
complete : power
    @echo "Build complete"
power : $(OBJECTS)
    $(CC) $(OPTIONS) -o $@ $^ -lm
    @echo "The executable is in the 'power' file"
main.o : main.h input.h compute.h
compute.o : compute.h
input.o : input.h
buldle :
    @echo "Archiving object modules..."
    ar $(AR_KEYS) $(LIBRARY) $(ARCHIVE)
    @echo "Archiving is complete."
power.tar : makefile $(HEADERS) $(SOURCES)
    tar -cvf $@ $^
clean :
    rm -f *.o

---------------------------------------------------------------------------------------------

庫的使用

在安裝庫文檔之前,需要給庫文檔生成和添加一個目錄索引。庫文檔中的目標文件不是以任意順序排列的,而是依賴于模塊被插入到庫文檔中的順序。帶有目錄的庫文檔在鏈接階段是必要的,它允許庫文檔中的函數互相調用,而無論這些函數在庫文檔中的位置如何。
ranlib 庫文檔列表
該命令可以為庫文檔列表中的每個庫文檔生成和添加一個目錄,該命令與如下命令相同:
ar s 庫文檔

一旦添加了目錄之后,就可以安裝該庫使其成為公有,主要采取兩個步驟:
1.創建庫的頭文件并把它放在/usr/include目錄中,頭文件包含庫中資源的聲明。一個庫文檔可以對應多個頭文件,例如libmath.a可以對應input.h和compute.h。
2.在/usr/lib目錄中放置該庫文檔,例如/usr/lib/libmath.a。
3.在使用該庫時,在程序中加入對應頭文件,并用帶有-lmath的編譯命令即可。

可以用nm命令顯示一個庫、目標或可執行文件的符號表,表中包括名稱、類型、大小和進入點等信息。它的輸出告知該庫的屬性,輸出的每一行是每一個標識符,例如文件中的某個函數名或者變量名。nm命令顯示的信息用于調試庫和可執行文件,對于庫文檔中的每個文件或成員,nm命令至少會將下面的信息發送到標準輸出:每個符號的地址、符號的值以及其類型。根據選項,也可能輸出庫或目標的名稱以及符號的大小等。

nm [選項] [文件列表(庫文件/目標文件/可執行文件)]
-D    只顯示動態符號,當使用動態庫時很有用
-V    nm命令版本號
-g    只顯示全局符號的相關信息
-l     為每一個符號查找和顯示文件名和行號
-n    用地址給外部符號分類
-u    只顯示未定義的符號,即每個目標模塊的外部符號
-w   給出更多警告信息
-f 格式    以不同格式輸出,可以是bsd、sysv、posix等,默認是bsd

對nm命令,以后再進行詳細學習,在此省略。