您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關(guān)linux下的lib文件的學(xué)習(xí)思考是什么,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
說到這個(gè)LIB文件,先從一個(gè)小故障說起。
某日開發(fā)說,一臺(tái)測(cè)試用虛機(jī)可以PING通SSH不能連了。運(yùn)維同學(xué)就趕緊去查,SSHD_CONFIG配置文件都正確啊,一點(diǎn)錯(cuò)誤都沒有,那為什么呢?
測(cè)試下,不管連自己還是其他機(jī),都是報(bào)錯(cuò)
這里注意看,提示你有個(gè)libcom_err.so.2共享庫文件找不到。
詢問開發(fā),才了解他們測(cè)試一個(gè)軟件,意外刪除了某個(gè)庫文件。
那么在正常的相同虛機(jī)的機(jī)器查看下,再和出錯(cuò)的虛機(jī)比對(duì)下,發(fā)現(xiàn)少了2個(gè)庫文件
掛載系統(tǒng)光盤或從正常的虛機(jī)上把這個(gè)兩個(gè)文件拷貝過來,放到lib64下就可以了
再試正常了
這個(gè)小故障很容易解決,那么你怎么理解linux中的庫文件呢?學(xué)習(xí)下也不誤工作。
Linux下的庫文件分為共享庫和靜態(tài)庫兩大類,它們兩者的差別僅在程序執(zhí)行時(shí)所需的代碼是在運(yùn)行時(shí)動(dòng)態(tài)加載的,還是在編譯時(shí)靜態(tài)加載的。
Linux的庫一般在/lib 或/usr/lib 目 錄下,如果是64位的系統(tǒng)則會(huì)有l(wèi)ib64目錄。lib是庫(Library)的英文縮寫,它主要存放系統(tǒng)的鏈接庫文件,沒有該目錄則系統(tǒng)就無法正常運(yùn)行。/lib目錄中存儲(chǔ)著程序運(yùn)行時(shí)使用的共享庫。通過共享庫,許多程序可以重復(fù)使用相同的代碼,并且這些庫可以存儲(chǔ)在一個(gè)公共的位置上,因此能減小運(yùn)行程序的大小。這個(gè)目錄包含程序在鏈接時(shí)使用的 各種庫。
庫的知識(shí)
1.庫的命名
庫的命名比較簡(jiǎn)單,第一個(gè)特點(diǎn)是所有的庫以lib開頭,GCC命令在在-l選項(xiàng)所指定的文件名前會(huì)自動(dòng)加入lib。
第二個(gè)特點(diǎn)文件名以.a結(jié)尾的庫是靜態(tài)庫。
第三個(gè)特點(diǎn)文件名是.so的庫為共享庫(共享庫是在運(yùn)行的時(shí)候動(dòng)態(tài)加載的 )。默認(rèn)情況下,GCC在鏈接時(shí)優(yōu)先使用共享庫,只有當(dāng)共享庫不存在時(shí)才考慮使用靜態(tài)庫。
2、庫的編號(hào)
庫的編號(hào)格式如下:
library_name .major.num .minor_.min .pathch_num
例如,筆者Red Hat Linux 9.0的GUN數(shù)據(jù)庫是libgdbm.so.0.0.2,詳細(xì)表述如下:
◆library_name是libc.so(標(biāo)準(zhǔn)C庫);
◆major_num是2(主版本號(hào));
◆minor_.min是0(次版本號(hào));
◆pathch_num是0(補(bǔ)丁級(jí)別號(hào)又稱發(fā)行號(hào))。
3、庫的操作命令
Linux庫操作可以使用命令完成,目前常用的命令是ldd和ldconfig。
ldd 是Library Dependency Display縮寫,它的作用是顯示一個(gè)可執(zhí)行程序必須使用的共享庫 。
(1)命令格式
ldd [選項(xiàng)] 文件名
(2)主要參數(shù)
-d 執(zhí)行重定位并報(bào)告丟失的函數(shù)。
-r 執(zhí)行對(duì)函數(shù)和數(shù)據(jù)對(duì)象的重定位,并報(bào)告丟失的函數(shù)和數(shù)據(jù)對(duì)象。
(3)應(yīng)用舉例
比如查詢Perl語言有哪些共享庫,則可以首先使用find命令查詢這個(gè)程序的絕對(duì)路徑,然后使用ldd命令:
#find -name perl
ldd /usr/bin/perl
$ ldd test
執(zhí)行test,可以看到它是如何調(diào)用動(dòng)態(tài)庫中的函數(shù)的。
2.ldconfig
ldconfig 命令的作用是決定位于目錄/usr/lib和/lib下的共享庫所需的運(yùn)行鏈接。這些鏈接保存在的Libs保存在/et/ld.so.conf文件中。搜 索出可共享的動(dòng)態(tài)鏈接庫(格式如前介紹,lib*.so*),進(jìn)而創(chuàng)建出動(dòng)態(tài)裝入程序(ld.so)所需的鏈接和緩存文件。緩存文件默認(rèn)為/etc /ld.so.cache,此文件保存已排好序的動(dòng)態(tài)鏈接庫名字列表。
(1)命令格式
ldconfig [選項(xiàng)] [libs]
(2)主要選項(xiàng)
-v或--verbose ldconfig將顯示正在掃描的目錄、搜索到的動(dòng)態(tài)鏈接庫,以及它所創(chuàng)建的連接的名字。
-f CONF 指定動(dòng)態(tài)鏈接庫的配置文件為CONF,系統(tǒng)默認(rèn)為/etc/ld.so.conf。
-C CACHE 指定生成的緩存文件為CACHE,系統(tǒng)默認(rèn)的是/etc/ld.so.cache,文件存放已排好序的可共享的動(dòng)態(tài)鏈接庫的列表。
-p或--print-cache 讓ldconfig打印出當(dāng)前緩存文件所保存的所有共享庫的名字。
-r ROOT 改變應(yīng)用程序的根目錄為ROOT。
-n ldconfig僅掃描命令行指定的目錄,不掃描默認(rèn)目錄(/lib、/usr/lib),也不掃描配置文件/etc/ld.so.conf所列的目錄。
運(yùn)行沒有選項(xiàng)的ldconfig命令時(shí),用于更新高速緩沖文件。這個(gè)命令主要用于高速緩沖DNS服務(wù)器(Caching DNS Server)。高速緩沖DNS服務(wù)器的原理是提供查詢的歷史記錄,并且利用這些記錄來提高查詢的效率。
當(dāng)某個(gè)查詢是第一次被發(fā)送到高速緩沖DNS服務(wù)器時(shí),高速緩沖DNS服務(wù)器就將此查詢的整個(gè)過程記錄下來,在一定的時(shí)期內(nèi)用它來回答所有相同的查詢,從而減少整個(gè)DNS系統(tǒng)的負(fù)擔(dān)并且提高查詢速度。
(3)應(yīng)用實(shí)例
如果用戶想知道系統(tǒng)中有哪些動(dòng)態(tài)鏈接庫,或者想知道系統(tǒng)中有沒有某個(gè)動(dòng)態(tài)鏈接庫時(shí),可用-p選項(xiàng)讓ldconfig輸出緩存文件中的動(dòng)態(tài)鏈接庫列表,從而查詢得到。 例如:
ldconfig -p
998 libs found in cache `/etc/ld.so.cache'
libzvt.so.2 (libc6) => /usr/lib/libzvt.so.2
libzvt.so (libc6) => /usr/lib/libzvt.so
……
補(bǔ)充:
靜態(tài)鏈接庫*.a的編譯和使用
創(chuàng)建.a庫文件和.o庫文件:
[yufei@localhost perl_c2]$ pwd
/home/yufei/perl_c2
[yufei@localhost perl_c2]$ cat mylib.c
#include <stdio.h>
#include <string.h>
void hello(){
printf("success call from perl to c library\n");
}
[yufei@localhost perl_c2]$ cat mylib.h
extern void hello();
[yufei@localhost perl_c2]$ gcc -c mylib.c
[yufei@localhost perl_c2]$ dir
mylib.c mylib.h mylib.o
[yufei@localhost perl_c2]$ ar -r mylib.a mylib.o
ar: 正在創(chuàng)建 mylib.a
[yufei@localhost perl_c2]$ dir
mylib.a mylib.c mylib.h mylib.o
*.a的使用方法
最簡(jiǎn)單的是直接把.a當(dāng)成一個(gè)普通源代碼編譯進(jìn)來.
gcc main.cpp ./lib/libInfo.a -o exec
動(dòng)態(tài)鏈接庫*.so的編譯與使用- -
動(dòng)態(tài)庫*.so在linux下用c和c++編程時(shí)經(jīng)常會(huì)碰到,這里做個(gè)筆記,也為其它正為動(dòng)態(tài)庫鏈接庫而苦惱的兄弟們提供一點(diǎn)幫助。
1、動(dòng)態(tài)庫的編譯
下面通過一個(gè)例子來介紹如何生成一個(gè)動(dòng)態(tài)庫。這里有一個(gè)頭文件:so_test.h,三個(gè).c文件:test_a.c、test_b.c、test_c.c,我們將這幾個(gè)文件編譯成一個(gè)動(dòng)態(tài)庫:libtest.so。
so_test.h:
#include <stdio.h>
#include <stdlib.h>
void test_a();
void test_b();
void test_c();
test_a.c:
#include "so_test.h"
void test_a()
{
printf("this is intest_a...\n");
}
test_b.c:
#include "so_test.h"
void test_b()
{
printf("this is intest_b...\n");
}
test_c.c:
#include "so_test.h"
void test_c()
{
printf("this is intest_c...\n");
}
將這幾個(gè)文件編譯成一個(gè)動(dòng)態(tài)庫:libtest.so
$ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so
2、動(dòng)態(tài)庫的鏈接
在1、中,我們已經(jīng)成功生成了一個(gè)自己的動(dòng)態(tài)鏈接庫libtest.so,下面我們通過一個(gè)程序來調(diào)用這個(gè)庫里的函數(shù)。程序的源文件為:test.c。
test.c:
#include "so_test.h"
int main()
{
test_a();
test_b();
test_c();
return 0;
}
l 將test.c與動(dòng)態(tài)庫libtest.so鏈接生成執(zhí)行文件test:
$ gcc test.c -L. -l test -o test
l 測(cè)試是否動(dòng)態(tài)連接,如果列出libtest.so,那么應(yīng)該是連接正常了
$ ldd test
l 執(zhí)行test,可以看到它是如何調(diào)用動(dòng)態(tài)庫中的函數(shù)的。
總結(jié):
1、共享庫特別適合多個(gè)程序共享代碼,升級(jí)程序部分功能模塊,實(shí)現(xiàn)程序“插件”功能的情況;
而靜態(tài)庫是一勞永逸,編譯后不需要帶一堆庫文件跑,而且不管放置到哪里都可正常運(yùn)行。
2、當(dāng)搜索的庫文件目錄下同時(shí)存在該庫的靜態(tài)版本和共享版本時(shí),鏈接器優(yōu)先使用共享版本.so,此時(shí)你可以使用-static鏈接選項(xiàng)指定鏈接靜態(tài)版本.a。
3、動(dòng)態(tài)庫可以導(dǎo)出兩個(gè)特殊的函數(shù):_init和_fini,前者在動(dòng)態(tài)庫被加載后調(diào)用,后者在動(dòng)態(tài)庫被卸載前調(diào)用,
我們可以使用這兩個(gè)函數(shù)做些特別的工作。需要注意的是:在定義這兩個(gè)函數(shù)后編譯時(shí),需要使用
-nostartfiles選項(xiàng),否則編譯器報(bào)重復(fù)定義錯(cuò)誤。
4、ldd命令用來查看程序所依賴的共享庫,同時(shí)也方便我們判斷共享庫是否被找到;
nm命令查看obj文件(.so也是一個(gè)obj)中的標(biāo)識(shí)(函數(shù)、變量)。
看完上述內(nèi)容,你們對(duì)linux下的lib文件的學(xué)習(xí)思考是什么有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。