靜態(tài)庫(.a)
靜態(tài)庫顧名思義是靜態(tài)的,即程序編譯鏈接時,會把靜態(tài)庫的代碼鏈接到可執(zhí)行文件中。運行時不需要靜態(tài)庫(將靜態(tài)庫刪了也能運行)。相當(dāng)于靜態(tài)庫的代碼復(fù)制到了可執(zhí)行文件中。
制作靜態(tài)庫
分別有如下add.c add.h sub.c sub.h四個文件格式。
- 首先把.c文件都編譯成.o文件。使用下面命令
//-c 編譯到二進制文件就停止
gcc -c add.c -o add.o
gcc -c sub.c -o sub.o
- 把.o打包的過程就是形成靜態(tài)庫的過程。使用下面命令:
# ar:archive file 歸檔文件 -rc:replace create
# libhello.a:lib是前綴名,必須加的;.a是靜態(tài)庫的后綴,必須加;hello是自己庫的名字
ar -rc libhello.a add.o sub.o
- 這樣我們的靜態(tài)庫就制作好啦。使用下面的命令可以查看靜態(tài)庫中的目錄列表:
# t:列出靜態(tài)庫中的文件
# v:verbose 詳細信息
ar -tv libhello.a
創(chuàng)建一個makefile來使編譯程序簡化:
如何使用靜態(tài)庫
首先將我們的庫函數(shù)放在一個文件夾里面:
運行完如下圖所示:
使用:main函數(shù)如下:
方法一:將該庫放到系統(tǒng)搜索的庫中。
頭文件gcc的默認搜索路徑是:/usr/include
庫文件的默認搜索路徑是:/lib64 or /usr/lib64
- 使用如下命令將自己的庫,復(fù)制到上面目錄中:
#復(fù)制頭文件
sudo cp ./hello/include/* /usr/include/ -rf
# 復(fù)制庫文件
sudo cp -rf ./hello/lib/* /lib64
- 使用該庫
為什么我們使用c語言庫不用告訴他鏈接哪個庫呢?
因為gcc是專門鏈接C語言的,他自己本身就設(shè)定好了,去哪個庫找。但是我們自己的庫,我們需要自己指定目錄。
# -l鏈接的意思 -lhello鏈接名字為hello的庫
# -static 選擇靜態(tài)鏈接的方式
gcc main.c -lhello -static //默認生成a.out
gcc -o main main.c -lhello -static //指定生成main可執(zhí)行文件
總結(jié):這種方法不推薦,因為涉及到更改系統(tǒng)目錄的內(nèi)容了。
我們再把那倆文件刪除:
sudo rm /usr/include/add.h /usr/include/sub.h
sudo rm /lib64/libhello.a
方法2:硬要使用。推薦
直接讓gcc找指定路徑的指定庫。
如下命令:
# -I:指定頭文件搜索路徑
# -L: 指定庫文件搜索路徑
# -lhello:指定使用哪個庫
gcc -o main main.c -I ./mklib/hello/include/ -L ./mklib/hello/lib/ -lhello
方法3:在系統(tǒng)的搜索路徑下,創(chuàng)建一個硬鏈接。也不推薦使用
動態(tài)庫(.so)
- 程序在運行的時候才去鏈接動態(tài)庫的代碼,多個程序共享使用庫的代碼。
- 一個動態(tài)庫鏈接的可執(zhí)行文件,僅僅包含用到的函數(shù)入口地址的一個表,而不是外部函數(shù)所在目標文件的整個機器碼。
- 在可執(zhí)行文件開始運行之前,外部函數(shù)的機器碼由操作系統(tǒng)從磁盤上的該動態(tài)庫中復(fù)制到內(nèi)存中,這個過程稱為動態(tài)鏈接。
- 動態(tài)庫可以在多個程序間共享,所以動態(tài)鏈接使得可執(zhí)行文件更小,節(jié)省了磁盤空間,OS采用虛擬內(nèi)存機制允許物理內(nèi)存中的一份動態(tài)數(shù)據(jù)庫被要用到該庫的所有進程共用,節(jié)省了內(nèi)存和磁盤空間。
制作動態(tài)庫
- 首先將.c文件變成與位置無關(guān)的二進制.o文件。
# -fPIC: 與二進制無關(guān)選項
gcc -fPIC -c add.c -o add_d.o
gcc -fPIC -c sub.c -o sub_d.o
- 將.o文件打包成動態(tài)庫
# -shared:動態(tài)庫選項
# libhello.so:lib是前綴,.so是后綴, hello是動態(tài)庫名字
gcc -shared add_d.o sub_d.o -o libhello.so
這樣我們的動態(tài)庫就制作成功啦。
如何使用動態(tài)庫(.so)
首先寫一個makefile方便制作動態(tài)庫。
hello文件結(jié)構(gòu)如圖所示:
仍然用靜態(tài)庫的那個命令(不加static了,默認就是動態(tài)鏈接),如下:
**解釋:**我們實際上用的方法是對的,也告訴gcc使用hello的庫了,并且默認也是動態(tài)鏈接。但是還是無法執(zhí)行。是因為,我們只是告訴gcc了,但是沒有告訴os,os在執(zhí)行此動態(tài)庫時,并不知道要去哪里把動態(tài)庫搬進內(nèi)存。因此我們要告訴,os去哪里找這個動態(tài)庫。
方法一:添加系統(tǒng)變量
- OS使用LD_LIBRARY_PATH加載環(huán)境變量。
將自己的庫的絕對路徑,添加到環(huán)境變量即可。
# 注意添加庫的路徑即可。
export LD_LIBRARY_PATH=$LD_LIBRARY:/home/xty/cplusplus/linux/20140110/mklib/hello/lib
總結(jié):不持久,重新登錄一次就又不能用了。因為環(huán)境變量會重新加載,我們弄得是臨時的環(huán)境變量。
方法二:修改配置文件
# 創(chuàng)建一個mylib.conf 配置文件,直接把庫的絕對路徑寫入即可。
sudo vim /etc/ld.so.conf.d/mylib.conf
# 更新緩存
sudo ldconfig
總結(jié):持久,推薦使用。文章來源:http://www.zghlxwxcb.cn/news/detail-820660.html
方法三:使用軟鏈接也可以
在/lib64/目錄里面,創(chuàng)建一個libhello.so軟鏈接,鏈接庫文件的地址。這個方法請讀者自行實現(xiàn),但是也不推薦,因為同樣更改了系統(tǒng)目錄內(nèi)容。文章來源地址http://www.zghlxwxcb.cn/news/detail-820660.html
到了這里,關(guān)于如何在linux下制作靜態(tài)庫和動態(tài)庫的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!