概述
linux下有兩種庫:動態庫和靜態庫 二者的不同點在於代碼被載入的時刻不同。
靜態庫的代碼在編譯過程中已經被載入可執行程序,因此體積比較大。
動態庫(共享庫)的代碼在可執行程序運行時才載入內存,在編譯過程中僅簡單的引用,因此代碼體積比較小。
不同的應用程序如果調用相同的庫,那麼在內存中只需要有一份該動態庫(共享庫)的實例。
靜態庫和動態庫的最大區別,靜態情況下,把庫直接加載到程序中,而動態庫鏈接的時候,它只是保留接口,將動態庫與程序代碼獨立,這樣就可以提高代碼的可複用度,和降低程序的耦合度。
靜態庫在程序編譯時會被複制到目標代碼中,程序運行時將不再需要該靜態庫。
動態庫在程序編譯時並不會被複制到目標代碼中,而是在程序運行是才被載入,因此在程序運行時還需要動態庫存在
-
靜態庫的編寫和使用
命名規則:lib庫名.a
-
將所有要加入靜態庫的模塊編譯爲目標文件.
juggler@ubuntu:~/uc/day03/t_math$ ls add.c main.c mul.c p_math.h juggler@ubuntu:~/uc/day03/t_math$ gcc -c add.c mul.c tarena@ubuntu:~/uc/day03/t_math$ ls add.c add.o main.c mul.c mul.o p_math.h
-
將第一步生成的目標文件打包到靜態庫文件中
juggler@ubuntu:~/uc/day03/t_math$ ar -r libpmath.a *.o ar: 正在創建 libpmath.a juggler@ubuntu:~/uc/day03/t_math$ ls add.c libpmath.a mul.c p_math.h add.o main.c mul.o
-
使用靜態庫文件鏈接生成可執行文件
juggler@ubuntu:~/uc/day03/t_math$ gcc -c main.c juggler@ubuntu:~/uc/day03/t_math$ gcc main.o -L. -lpmath juggler@ubuntu:~/uc/day03/t_math$ ls add.c a.out main.c mul.c p_math.h add.o libpmath.a main.o mul.o juggler@ubuntu:~/uc/day03/t_math$ ./a.out 6+2=8 -L路徑 鏈接器尋找庫文件的路徑 -l庫名 指定要找的庫的名字 -I 路徑 預處理時尋找頭文件的路徑
-
-
在UNIX中,使用ar命令創建或者操作靜態庫
ar archivefile objfile archivefile:archivefile是靜態庫的名稱 objfile:objfile是已.o爲擴展名的中間目標文件名,可以多個並列 參數 意義 -r 將objfile文件插入靜態庫尾或者替換靜態庫中同名文件 -x 從靜態庫文件中抽取文件objfile -t 打印靜態庫的成員文件列表 -d 從靜態庫中刪除文件objfile -s 重置靜態庫文件索引 -v 創建文件冗餘信息 -c 創建靜態庫文件
- 動態鏈接
-
動態鏈接庫的製作和使用
* 命名規則 lib庫名.so
-
將要加入動態庫的源文件編譯爲目標文件(與位置無關的目標文件)
t_math$ls add.c main.c mul.c p_math.h t_math$gcc -c -fPIC add.c mul.c t_math$ls add.c add.o main.c mul.c mul.o p_math.h -fPIC:生成與位置無關的目標文件
-
將第一步生成的目標文件打包到動態庫文件中
t_math$gcc -shared -o libpmath.so *.o t_math$ls add.c libpmath.so mul.c p_math.h add.o main.c mul.o
-
使用動態庫鏈接生成可執行文件
t_math$gcc main.c -L. -lpmath t_math$ls add.c a.out main.c mul.o add.o libpmath.so mul.c p_math.h t_math$a.out a.out: error while loading shared libraries: libpmath.so: cannot open shared object file: No such file or directory
-
使用靜態庫鏈接生成的可執行文件.從靜態庫中找到程序中使用的模塊,將這些模塊合併到可執行文件中.可執行文件是獨立的文件.不再依賴靜態庫文件.
-
使用動態庫生成的可執行文件.和動態庫是兩個獨立的模塊.這種可執行文件要執行的時候,必須將可執行文件和動態庫一起加載到內存.
-
需要指到可執行文件依賴哪些動態庫文件?
ldd a.out -
告訴動態鏈接器到哪裏去找動態庫文件.
兩種方法解決-
使用LD_LIBRARY_PATH環境變量告訴動態鏈接器
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
-
鏈接器默認的搜索路徑是/lib或者/usr/lib
mv libpmath.so /lib mv libpmath.so /usr/lib
-
-