Linux学习:静态库和动态库
1、庫(kù)是什么?
將“源代碼”變?yōu)椤岸M(jìn)制格式的源代碼”(作用:加密,別人可以用,但不知道其中的內(nèi)容)。
2、庫(kù)制作出來(lái)之后,如何給用戶使用?
需要給用戶:頭文件(內(nèi)含接口聲明,相當(dāng)于說(shuō)明書(shū)),制作的庫(kù)。
3、靜態(tài)庫(kù)的制作和使用(windows 中叫 .lib 庫(kù) Linux 叫.a 庫(kù))
(1)命名規(guī)則:libxxx.a,其中
lib: 靜態(tài)庫(kù)標(biāo)識(shí)
xxx :庫(kù)的實(shí)際名字
.a :Linux 靜態(tài)庫(kù)的后綴
(2) 制作步驟:
1)準(zhǔn)備原材料:源代碼.c /.cpp 例:a.c 和b.c。
2)將 .c 文件 生成 .o 文件 例:gcc a.c b.c -c // 生成 a.o b.o。
3)將 .o 文件 打包 .a 庫(kù)文件 例:ar rcs libxxx.a a.o b.o。
4)發(fā)布: 將頭文件(放入 include 目錄)和庫(kù)文件(放入 lib 目錄),交給用戶。
注意:查看靜態(tài)庫(kù)內(nèi)容(包含什么 .o 文件): nm libxxx.a
(3)靜態(tài)庫(kù)使用:
1)使用時(shí)候,test.c 中要包含靜態(tài)庫(kù)的頭文件。
2)在 test.c 中直接調(diào)用靜態(tài)庫(kù)中函數(shù)接口。
3)主要在編譯:gcc test.c -I ./include/ -L ./ilb -l xxx -o app : 生成 app 可執(zhí)行程序。
注意:-I 是指定庫(kù)的名字(掐頭去尾)
4、動(dòng)態(tài)庫(kù)的制作和使用(windows 是 .dll 庫(kù) Linux 是.so 庫(kù))
(1)命名規(guī)則:libxxx.so
(2)制作步驟:注意 gcc 參數(shù)
1)準(zhǔn)備原材料:源代碼.c /.cpp 例:a.c b.c
2)將源文件生成.o 文件 例:gcc a.c b.c -c -fpic。
3)將 .o 文件 打包 .so 庫(kù)文件 例:gcc -shared a.o b.o -o libxxx.so 。
4)發(fā)布:將頭文件(放入 include 目錄)和庫(kù)文件(放入 lib 目錄),交給用戶。
(3)動(dòng)態(tài)庫(kù)使用:
編譯生成 app 可執(zhí)行文件:gcc test.c -I ./include/ -L ./ilb -l xxx -o app
注意:此時(shí)直接運(yùn)行程序 ./app,會(huì)動(dòng)態(tài)加載失敗(找不到 libxxx.so),會(huì)報(bào)錯(cuò)!
error while loading shared libraries:libxxx.so:cannot open shared object file:NO such file or dirrctory
本質(zhì):ldd app(檢測(cè) app 需要的所有動(dòng)態(tài)庫(kù)的存放路徑和地址) 會(huì)發(fā)現(xiàn) libxxx.so 出現(xiàn)not found
原因:
系統(tǒng)會(huì)先后從以下 4 個(gè)位置下尋找 動(dòng)態(tài)庫(kù)的路徑,然后由動(dòng)態(tài)連接器加載:
1)elf 文件的 DT_RPATH 段(位于可執(zhí)行文件內(nèi)部,不好修改)
2)環(huán)境變量 LD_LIBRARY_PATH
3)/etc/ld.so.cache 文件列表
4)/lib/ 或者 /user/lib 目錄
解決:
方式 1:將 .so 文件拷貝至 /lib 目錄(或者 /usr/lib 目錄)
sudo cp lib/libxxx.so /lib
此方法不推薦:因?yàn)槊總€(gè)人都放入這個(gè)目錄,如果有動(dòng)態(tài)庫(kù)重名,會(huì)出現(xiàn)覆蓋的情況。
方式 2:更新 /etc/ld.so.cache 文件列表 (推薦此方法)
sudo vi /etc/ld.so.conf -> 添加存放動(dòng)態(tài)庫(kù)的絕對(duì)路徑 ->執(zhí)行更新命令:sudo ldconfig
方式 3:設(shè)置環(huán)境變量
臨時(shí)設(shè)置:關(guān)閉終端后會(huì)失效,只供測(cè)試用。
終端輸入命令 :export LD_LIBRARY_PATH =存放動(dòng)態(tài)庫(kù)的絕對(duì)路徑:$LD_LIBRARY_PATH
永久設(shè)置:
(1)用戶級(jí)別 :
vi ~/.bashrc(打開(kāi)配置文件)->將上方命令寫入 -> 完成后重啟終端。
(2)全局級(jí)別 :
vi /etc/profile(打開(kāi)配置文件)->將上方命令寫入 ->完成后重啟終端。
5、 靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的區(qū)別
(1)靜態(tài)庫(kù):靜態(tài)庫(kù)被打包到應(yīng)用程序中,即使不執(zhí)行程序,庫(kù)代碼仍然在 app 中。
優(yōu)點(diǎn):使用簡(jiǎn)單;執(zhí)行快;發(fā)布應(yīng)用程序不需要發(fā)布庫(kù)。
缺點(diǎn):代碼空間較大;庫(kù)變更時(shí)應(yīng)用程序需要重新編譯。
(2)動(dòng)態(tài)庫(kù):動(dòng)態(tài)庫(kù)沒(méi)有被打包到應(yīng)用程序中,只有在程序調(diào)用庫(kù)函數(shù)的時(shí)候才會(huì)調(diào)用動(dòng)態(tài)庫(kù)。
優(yōu)點(diǎn):程序體積小;庫(kù)變更時(shí)程序不需要重新編譯(注意:函數(shù)接口變化,需要重新編譯)。
缺點(diǎn):使用相對(duì)麻煩(需要解決動(dòng)態(tài)加載問(wèn)題);執(zhí)行慢;發(fā)布應(yīng)用程序時(shí)需要發(fā)布庫(kù)。
總結(jié)
以上是生活随笔為你收集整理的Linux学习:静态库和动态库的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Linux学习:gcc 编译其他常用参数
- 下一篇: Linux学习:makefile介绍