青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-4  評(píng)論-40  文章-117  trackbacks-0


一、基本概念

1.1什么是庫(kù)

在windows平臺(tái)和linux平臺(tái)下都大量存在著庫(kù)。

本質(zhì)上來(lái)說(shuō)庫(kù)是一種可執(zhí)行代碼的二進(jìn)制形式,可以被操作系統(tǒng)載入內(nèi)存執(zhí)行。

由于windows和linux的平臺(tái)不同(主要是編譯器、匯編器和連接器的不同),因此二者庫(kù)的二進(jìn)制是不兼容的。

本文僅限于介紹linux下的庫(kù)。

 

 

1.2庫(kù)的種類

linux下的庫(kù)有兩種:靜態(tài)庫(kù)和共享庫(kù)(動(dòng)態(tài)庫(kù))。

二者的不同點(diǎn)在于代碼被載入的時(shí)刻不同。

靜態(tài)庫(kù)的代碼在編譯過(guò)程中已經(jīng)被載入可執(zhí)行程序,因此體積較大。

共享庫(kù)的代碼是在可執(zhí)行程序運(yùn)行時(shí)才載入內(nèi)存的,在編譯過(guò)程中僅簡(jiǎn)單的引用,因此代碼體積較小。

 

 

1.3庫(kù)存在的意義

庫(kù)是別人寫(xiě)好的現(xiàn)有的,成熟的,可以復(fù)用的代碼,你可以使用但要記得遵守許可協(xié)議。

現(xiàn)實(shí)中每個(gè)程序都要依賴很多基礎(chǔ)的底層庫(kù),不可能每個(gè)人的代碼都從零開(kāi)始,因此庫(kù)的存在意義非同尋常。

共享庫(kù)的好處是,不同的應(yīng)用程序如果調(diào)用相同的庫(kù),那么在內(nèi)存里只需要有一份該共享庫(kù)的實(shí)例。

 

 

1.4庫(kù)文件是如何產(chǎn)生的在linux下

靜態(tài)庫(kù)的后綴是.a,它的產(chǎn)生分兩步

Step 1.由源文件編譯生成一堆.o,每個(gè).o里都包含這個(gè)編譯單元的符號(hào)表

Step 2.ar命令將很多.o轉(zhuǎn)換成.a,成為靜態(tài)庫(kù)

動(dòng)態(tài)庫(kù)的后綴是.so,它由gcc加特定參數(shù)編譯產(chǎn)生。

具體方法參見(jiàn)后文實(shí)例。

 

1.5庫(kù)文件是如何命名的,有沒(méi)有什么規(guī)范

在linux下,庫(kù)文件一般放在/usr/lib和/lib下,

靜態(tài)庫(kù)的名字一般為libxxxx.a,其中xxxx是該lib的名稱

動(dòng)態(tài)庫(kù)的名字一般為libxxxx.so.major.minor,xxxx是該lib的名稱,major是主版本號(hào), minor是副版本號(hào)

 

 

1.6如何知道一個(gè)可執(zhí)行程序依賴哪些庫(kù)

ldd命令可以查看一個(gè)可執(zhí)行程序依賴的共享庫(kù),

例如# ldd /bin/lnlibc.so.6

=> /lib/libc.so.6 (0×40021000)/lib/ld-linux.so.2

=> /lib/ld- linux.so.2 (0×40000000)

可以看到ln命令依賴于libc庫(kù)和ld-linux庫(kù)

 

 

1.7可執(zhí)行程序在執(zhí)行的時(shí)候如何定位共享庫(kù)文件

當(dāng)系統(tǒng)加載可執(zhí)行代碼時(shí)候,能夠知道其所依賴的庫(kù)的名字,但是還需要知道絕對(duì)路徑。

此時(shí)就需要系統(tǒng)動(dòng)態(tài)載入器(dynamic linker/loader)

對(duì)于elf格式的可執(zhí)行程序,是由ld-linux.so*來(lái)完成的,它先后搜索elf文件的 DT_RPATH段—環(huán)境變量LD_LIBRARY_PATH—/etc/ld.so.cache文件列表—/lib/,/usr/lib目錄找到庫(kù)文件后將其載入內(nèi)存

如:export LD_LIBRARY_PATH=’pwd’

將當(dāng)前文件目錄添加為共享目錄

 

1.8在新安裝一個(gè)庫(kù)之后如何讓系統(tǒng)能夠找到他

如果安裝在/lib或者/usr/lib下,那么ld默認(rèn)能夠找到,無(wú)需其他操作。

如果安裝在其他目錄,需要將其添加到/etc/ld.so.cache文件中,步驟如下

1.編輯/etc/ld.so.conf文件,加入庫(kù)文件所在目錄的路徑

2.運(yùn)行l(wèi)dconfig,該命令會(huì)重建/etc/ld.so.cache文件


二、用gcc生成靜態(tài)和動(dòng)態(tài)鏈接庫(kù)的示例

我們通常把一些公用函數(shù)制作成函數(shù)庫(kù),供其它程序使用。

函數(shù)庫(kù)分為靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)兩種。

 

靜態(tài)庫(kù)在程序編譯時(shí)會(huì)被連接到目標(biāo)代碼中,程序運(yùn)行時(shí)將不再需要該靜態(tài)庫(kù)。

 

動(dòng)態(tài)庫(kù)在程序編譯時(shí)并不會(huì)被連接到目標(biāo)代碼中,而是在程序運(yùn)行是才被載入,因此在程序運(yùn)行時(shí)還需要?jiǎng)討B(tài)庫(kù)存在。

 

本文主要通過(guò)舉例來(lái)說(shuō)明在Linux中如何創(chuàng)建靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù),以及使用它們。

 

為了便于闡述,我們先做一部分準(zhǔn)備工作。

 

2.1準(zhǔn)備好測(cè)試代碼hello.h、hello.c和main.c;

hello.h(見(jiàn)程序1)為該函數(shù)庫(kù)的頭文件。

 

hello.c(見(jiàn)程序2)是函數(shù)庫(kù)的源程序,其中包含公用函數(shù)hello,該函數(shù)將在屏幕上輸出"Hello XXX!"。

 

main.c(見(jiàn)程序3)為測(cè)試庫(kù)文件的主程序,在主程序中調(diào)用了公用函數(shù)hello。

 

 程序1: hello.h

#ifndef HELLO_H 
#define HELLO_H 
  
void hello(const char *name); 
  
#endif


程序2:hello.c

#include <stdio.h> 
void hello(const char *name) { 

        printf("Hello %s!\n", name); 
}


程序3:main.c

#include "hello.h" 
 int main() 
 { 
     hello("everyone"); 
     return 0; 
 }

2.2問(wèn)題的提出

注意:這個(gè)時(shí)候,我們編譯好的hello.o是無(wú)法通過(guò)gcc –o 編譯的,這個(gè)道理非常簡(jiǎn)單,

hello.c是一個(gè)沒(méi)有main函數(shù)的.c程序,因此不夠成一個(gè)完整的程序,如果使用gcc –o 編譯并連接它,GCC將報(bào)錯(cuò)。

無(wú)論靜態(tài)庫(kù),還是動(dòng)態(tài)庫(kù),都是由.o文件創(chuàng)建的。因此,我們必須將源程序hello.c通過(guò)gcc先編譯成.o文件。

這個(gè)時(shí)候我們有三種思路:

1)  通過(guò)編譯多個(gè)源文件,直接將目標(biāo)代碼合成一個(gè).o文件。

2)  通過(guò)創(chuàng)建靜態(tài)鏈接庫(kù)libmyhello.a,使得main函數(shù)調(diào)用hello函數(shù)時(shí)可調(diào)用靜態(tài)鏈接庫(kù)。

3)  通過(guò)創(chuàng)建動(dòng)態(tài)鏈接庫(kù)libmyhello.so,使得main函數(shù)調(diào)用hello函數(shù)時(shí)可調(diào)用靜態(tài)鏈接庫(kù)。

2.3思路一:編譯多個(gè)源文件

在系統(tǒng)提示符下鍵入以下命令得到hello.o文件。

# gcc -c hello.c

為什么不使用gcc–o hello hello.cpp 這個(gè)道理我們之前已經(jīng)說(shuō)了,使用-c是什么意思呢?這涉及到gcc 編譯選項(xiàng)的常識(shí)。

 

我們通常使用的gcc –o 是將.c源文件編譯成為一個(gè)可執(zhí)行的二進(jìn)制代碼(-o選項(xiàng)其實(shí)是制定輸出文件文件名,如果不加-c選項(xiàng),gcc默認(rèn)會(huì)編譯連接生成可執(zhí)行文件,文件的名稱有-o選項(xiàng)指定),這包括調(diào)用作為GCC內(nèi)的一部分真正的C編譯器(ccl),以及調(diào)用GNU C編譯器的輸出中實(shí)際可執(zhí)行代碼的外部GNU匯編器(as)和連接器工具(ld)。

gcc –c是使用GNU匯編器將源文件轉(zhuǎn)化為目標(biāo)代碼之后就結(jié)束,在這種情況下,只調(diào)用了C編譯器(ccl)和匯編器(as),而連接器(ld)并沒(méi)有被執(zhí)行,所以輸出的目標(biāo)文件不會(huì)包含作為Linux程序在被裝載和執(zhí)行時(shí)所必須的包含信息,但它可以在以后被連接到一個(gè)程序。

我們運(yùn)行ls命令看看是否生存了hello.o文件。

# ls

hello.c hello.h hello.o main.c

 

ls命令結(jié)果中,我們看到了hello.o文件,本步操作完成。

 

同理編譯main

#gcc –c main.c

 

將兩個(gè)文件鏈接成一個(gè).o文件。

#gcc –o hello hello.o main.o

 

運(yùn)行

# ./hello

 

Hello everyone!

 

完成^ ^!

2.4思路二:靜態(tài)鏈接庫(kù)

 

下面我們先來(lái)看看如何創(chuàng)建靜態(tài)庫(kù),以及使用它。

 

靜態(tài)庫(kù)文件名的命名規(guī)范是以lib為前綴,緊接著跟靜態(tài)庫(kù)名,擴(kuò)展名為.a。例如:我們將創(chuàng)建的靜態(tài)庫(kù)名為myhello,則靜態(tài)庫(kù)文件名就是libmyhello.a。在創(chuàng)建和使用靜態(tài)庫(kù)時(shí),需要注意這點(diǎn)。創(chuàng)建靜態(tài)庫(kù)用ar命令

 

在系統(tǒng)提示符下鍵入以下命令將創(chuàng)建靜態(tài)庫(kù)文件libmyhello.a

 

# ar rcs libmyhello.a hello.o

 

 

我們同樣運(yùn)行ls命令查看結(jié)果:

 

# ls

 

hello.c  hello.h hello.o libmyhello.a main.c

 

ls命令結(jié)果中有libmyhello.a

 

靜態(tài)庫(kù)制作完了,如何使用它內(nèi)部的函數(shù)呢?只需要在使用到這些公用函數(shù)的源程序中包含這些公用函數(shù)的原型聲明,然后在用gcc命令生成目標(biāo)文件時(shí)指明靜態(tài)庫(kù)名,gcc將會(huì)從靜態(tài)庫(kù)中將公用函數(shù)連接到目標(biāo)文件中。注意,gcc會(huì)在靜態(tài)庫(kù)名前加上前綴lib,然后追加擴(kuò)展名.a得到的靜態(tài)庫(kù)文件名來(lái)查找靜態(tài)庫(kù)文件,因此,我們?cè)趯?xiě)需要連接的庫(kù)時(shí),只寫(xiě)名字就可以,如libmyhello.a的庫(kù),只寫(xiě):-lmyhello

 

在程序3:main.c中,我們包含了靜態(tài)庫(kù)的頭文件hello.h,然后在主程序main中直接調(diào)用公用函數(shù)hello。下面先生成目標(biāo)程序hello,然后運(yùn)行hello程序看看結(jié)果如何。

 

# gcc -o hello main.c -static -L. -lmyhello

 

# ./hello

 

Hello everyone!

 

我們刪除靜態(tài)庫(kù)文件試試公用函數(shù)hello是否真的連接到目標(biāo)文件 hello中了。

 

# rm libmyhello.a

 

rm: remove regular file `libmyhello.a'? y

 

# ./hello

 

Hello everyone!

 

程序照常運(yùn)行,靜態(tài)庫(kù)中的公用函數(shù)已經(jīng)連接到目標(biāo)文件中了。

靜態(tài)鏈接庫(kù)的一個(gè)缺點(diǎn)是,如果我們同時(shí)運(yùn)行了許多程序,并且它們使用了同一個(gè)庫(kù)函數(shù),這樣,在內(nèi)存中會(huì)大量拷貝同一庫(kù)函數(shù)。這樣,就會(huì)浪費(fèi)很多珍貴的內(nèi)存和存儲(chǔ)空間。使用了共享鏈接庫(kù)的Linux就可以避免這個(gè)問(wèn)題。

共享函數(shù)庫(kù)和靜態(tài)函數(shù)在同一個(gè)地方,只是后綴有所不同。比如,在一個(gè)典型的Linux系統(tǒng),標(biāo)準(zhǔn)的共享數(shù)序函數(shù)庫(kù)是/usr/lib/libm.so。

當(dāng)一個(gè)程序使用共享函數(shù)庫(kù)時(shí),在連接階段并不把函數(shù)代碼連接進(jìn)來(lái),而只是鏈接函數(shù)的一個(gè)引用。當(dāng)最終的函數(shù)導(dǎo)入內(nèi)存開(kāi)始真正執(zhí)行時(shí),函數(shù)引用被解析,共享函數(shù)庫(kù)的代碼才真正導(dǎo)入到內(nèi)存中。這樣,共享鏈接庫(kù)的函數(shù)就可以被許多程序同時(shí)共享,并且只需存儲(chǔ)一次就可以了。共享函數(shù)庫(kù)的另一個(gè)優(yōu)點(diǎn)是,它可以獨(dú)立更新,與調(diào)用它的函數(shù)毫不影響。

2.5思路三、動(dòng)態(tài)鏈接庫(kù)(共享函數(shù)庫(kù))

 

我們繼續(xù)看看如何在Linux中創(chuàng)建動(dòng)態(tài)庫(kù)。我們還是從.o文件開(kāi)始。

 

動(dòng)態(tài)庫(kù)文件名命名規(guī)范和靜態(tài)庫(kù)文件名命名規(guī)范類似,也是在動(dòng)態(tài)庫(kù)名增加前綴lib,但其文件擴(kuò)展名為.so。例如:我們將創(chuàng)建的動(dòng)態(tài)庫(kù)名為myhello,則動(dòng)態(tài)庫(kù)文件名就是libmyhello.so。用gcc來(lái)創(chuàng)建動(dòng)態(tài)庫(kù)。

 

在系統(tǒng)提示符下鍵入以下命令得到動(dòng)態(tài)庫(kù)文件libmyhello.so

 

# gcc -shared -fPIC -o libmyhello.so hello.o

 

 “PIC”命令行標(biāo)記告訴GCC產(chǎn)生的代碼不要包含對(duì)函數(shù)和變量具體內(nèi)存位置的引用,這是因?yàn)楝F(xiàn)在還無(wú)法知道使用該消息代碼的應(yīng)用程序會(huì)將它連接到哪一段內(nèi)存地址空間。這樣編譯出的hello.o可以被用于建立共享鏈接庫(kù)。建立共享鏈接庫(kù)只需要用GCC”-shared”標(biāo)記即可。

 

我們照樣使用ls命令看看動(dòng)態(tài)庫(kù)文件是否生成。

 

# ls

 

hello.cpp hello.h hello.o libmyhello.so main.cpp

調(diào)用動(dòng)態(tài)鏈接庫(kù)編譯目標(biāo)文件。

 

在程序中使用動(dòng)態(tài)庫(kù)和使用靜態(tài)庫(kù)完全一樣,也是在使用到這些公用函數(shù)的源程序中包含這些公用函數(shù)的原型聲明,然后在用gcc命令生成目標(biāo)文件時(shí)指明動(dòng)態(tài)庫(kù)名進(jìn)行編譯。我們先運(yùn)行gcc命令生成目標(biāo)文件,再運(yùn)行它看看結(jié)果。

 

如果直接用如下方法進(jìn)行編譯,并連接:

# gcc -o hello main.c -L. -lmyhello

 

(使用”-lmyhello”標(biāo)記來(lái)告訴GCC驅(qū)動(dòng)程序在連接階段引用共享函數(shù)庫(kù)libmyhello.so”-L.”標(biāo)記告訴GCC函數(shù)庫(kù)可能位于當(dāng)前目錄。否則GNU連接器會(huì)查找標(biāo)準(zhǔn)系統(tǒng)函數(shù)目錄:它先后搜索1.elf文件的 DT_RPATH段—2.環(huán)境變量LD_LIBRARY_PATH—3./etc/ld.so.cache文件列表—4./lib/,/usr/lib目錄找到庫(kù)文件后將其載入內(nèi)存,但是我們生成的共享庫(kù)在當(dāng)前文件夾下,并沒(méi)有加到上述的4個(gè)路徑的任何一個(gè)中,因此,執(zhí)行后會(huì)出現(xiàn)錯(cuò)誤)

 

# ./hello

 

./hello: error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory

 

#

錯(cuò)誤提示,找不到動(dòng)態(tài)庫(kù)文件libmyhello.so。程序在運(yùn)行時(shí),會(huì)在/usr/lib/lib等目錄中查找需要的動(dòng)態(tài)庫(kù)文件。若找到,則載入動(dòng)態(tài)庫(kù),否則將提示類似上述錯(cuò)誤而終止程序運(yùn)行。有多種方法可以解決,

(1)我們將文件 libmyhello.so復(fù)制到目錄/usr/lib中,再試試。

 

# mv libmyhello.so /usr/lib

 

# ./hello

成功!

(2)既然連接器會(huì)搜尋LD_LIBRARY_PATH所指定的目錄,那么我們可以將這個(gè)環(huán)境變量設(shè)置成當(dāng)前目錄:

先執(zhí)行:

export LD_LIBRARY_PATH=$(pwd)

再執(zhí)行:

./hello

成功!

(3)

執(zhí)行:  

ldconfig   /usr/zhsoft/lib     
       
      
  注:   當(dāng)用戶在某個(gè)目錄下面創(chuàng)建或拷貝了一個(gè)動(dòng)態(tài)鏈接庫(kù),若想使其被系統(tǒng)共享,可以執(zhí)行一下"ldconfig   目錄名"這個(gè)命令.此命令的功能在于讓ldconfig將指定目錄下的動(dòng)態(tài)鏈接庫(kù)被系統(tǒng)共享起來(lái),意即:在緩存文件/etc/ld.so.cache中追加進(jìn)指定目錄下的共享庫(kù).本例讓系統(tǒng)共享了/usr/zhsoft/lib目錄下的動(dòng)態(tài)鏈接庫(kù).該命令會(huì)重建/etc/ld.so.cache文件

 

成功!

¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥

下面的這個(gè)錯(cuò)誤我沒(méi)有遇到,不過(guò)也記錄下,給遇到的人:

 {  這步后我沒(méi)有成功,報(bào)錯(cuò)內(nèi)容如下:/hello: error while loading shared libraries: /usr/lib/libmyhello.so: cannot restore segment prot after reloc: Permission denied

google了一下,發(fā)現(xiàn)是SELinux搞的鬼,解決辦法有兩個(gè):

1.
    chcon -t texrel_shlib_t   
/usr/lib/libmyhello.so
    (chcon -t texrel_shlib_t "你不能share的庫(kù)的絕對(duì)路徑")

2.
    #vi /etc/sysconfig/selinux file
    或者用
    #gedit /etc/sysconfig/selinux file
    修改SELINUX=disabled
    重啟

}

#

¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥

這也進(jìn)一步說(shuō)明了動(dòng)態(tài)庫(kù)在程序運(yùn)行時(shí)是需要的。

 

可以查看程序執(zhí)行時(shí)調(diào)用動(dòng)態(tài)庫(kù)的過(guò)程:

# ldd hello
執(zhí)行 test,可以看到它是如何調(diào)用動(dòng)態(tài)庫(kù)中的函數(shù)的。
[pin@localhost 20090505]$ ldd hello
        linux-gate.so.1 => (0x00110000)
        libmyhello.so => /usr/lib/libmyhello.so (0x00111000)
        libc.so.6 => /lib/libc.so.6 (0x00859000)
        /lib/ld-linux.so.2 (0x0083a000)

我們回過(guò)頭看看,發(fā)現(xiàn)使用靜態(tài)庫(kù)和使用動(dòng)態(tài)庫(kù)編譯成目標(biāo)程序使用的gcc命令完全一樣,
那當(dāng)靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)同名時(shí),gcc命令會(huì)使用哪個(gè)庫(kù)文件呢?抱著對(duì)問(wèn)題必究到底的心情,
來(lái)試試看。

先刪除除.c和.h外的所有文件,恢復(fù)成我們剛剛編輯完舉例程序狀態(tài)。

# rm -f hello hello.o /usr/lib/libmyhello.so

# ls

hello.c hello.h main.c

#

在來(lái)創(chuàng)建靜態(tài)庫(kù)文件libmyhello.a和動(dòng)態(tài)庫(kù)文件libmyhello.so。

# gcc -c hello.c

# ar rcs libmyhello.a hello.o

# gcc -shared -fPCI -o libmyhello.so hello.o

# ls

hello.c hello.h hello.o libmyhello.a libmyhello.so main.c

#

通過(guò)上述最后一條ls命令,可以發(fā)現(xiàn)靜態(tài)庫(kù)文件libmyhello.a和動(dòng)態(tài)庫(kù)文件libmyhello.so都已經(jīng)生成,并都在當(dāng)前目錄中。然后,我們運(yùn)行g(shù)cc命令來(lái)使用函數(shù)庫(kù)myhello生成目標(biāo)文件hello,并運(yùn)行程序 hello。

# gcc -o hello main.c -L. -lmyhello

# ./hello

./hello: error while loading shared libraries: libmyhello.so: cannot open shar
ed object file: No such file or directory

#

從程序hello運(yùn)行的結(jié)果中很容易知道,當(dāng)靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)同名時(shí), gcc命令將優(yōu)先使用動(dòng)態(tài)庫(kù)。

Note:

編譯參數(shù)解析


最主要的是GCC命令行的一個(gè)選項(xiàng):
-shared 該選項(xiàng)指定生成動(dòng)態(tài)連接庫(kù)(讓連接器生成T類型的導(dǎo)出符號(hào)表,有時(shí)候也生成弱連接W類型的導(dǎo)出符號(hào)),不用該標(biāo)志外部程序無(wú)法連接。相當(dāng)于一個(gè)可執(zhí)行文件
l -fPIC:表示編譯為位置獨(dú)立的代碼,不用此選項(xiàng)的話編譯后的代碼是位置相關(guān)的所以動(dòng)態(tài)載入時(shí)是通過(guò)代碼拷貝的方式來(lái)滿足不同進(jìn)程的需要,而不能達(dá)到真正代碼段共享的目的。
l -L.:表示要連接的庫(kù)在當(dāng)前目錄中
l -ltest:編譯器查找動(dòng)態(tài)連接庫(kù)時(shí)有隱含的命名規(guī)則,即在給出的名字前面加上lib,后面加上.so來(lái)確定庫(kù)的名稱
l LD_LIBRARY_PATH:這個(gè)環(huán)境變量指示動(dòng)態(tài)連接器可以裝載動(dòng)態(tài)庫(kù)的路徑。
l 當(dāng)然如果有root權(quán)限的話,可以修改/etc/ld.so.conf文件,然后調(diào)用 /sbin/ldconfig來(lái)達(dá)到同樣的目的,不過(guò)如果沒(méi)有root權(quán)限,那么只能采用輸出LD_LIBRARY_PATH的方法了。

調(diào)用動(dòng)態(tài)庫(kù)的時(shí)候有幾個(gè)問(wèn)題會(huì)經(jīng)常碰到,有時(shí),明明已經(jīng)將庫(kù)的頭文件所在目錄 通過(guò) “-I” include進(jìn)來(lái)了,庫(kù)所在文件通過(guò) “-L”參數(shù)引導(dǎo),并指定了“-l”的庫(kù)名,但通過(guò)ldd命令察看時(shí),就是死活找不到你指定鏈接的so文件,這時(shí)你要作的就是通過(guò)修改 LD_LIBRARY_PATH或者/etc/ld.so.conf文件來(lái)指定動(dòng)態(tài)庫(kù)的目錄。通常這樣做就可以解決庫(kù)無(wú)法鏈接的問(wèn)題了。


靜態(tài)庫(kù)鏈接時(shí)搜索路徑順序:

1. ld會(huì)去找GCC命令中的參數(shù)-L

2. 再找gcc的環(huán)境變量LIBRARY_PATH

3. 再找內(nèi)定目錄 /lib /usr/lib /usr/local/lib 這是當(dāng)初compile gcc時(shí)寫(xiě)在程序內(nèi)的


動(dòng)態(tài)鏈接時(shí)、執(zhí)行時(shí)搜索路徑順序:


1.  編譯目標(biāo)代碼時(shí)指定的動(dòng)態(tài)庫(kù)搜索路徑;

2.  環(huán)境變量LD_LIBRARY_PATH指定的動(dòng)態(tài)庫(kù)搜索路徑;

3.  配置文件/etc/ld.so.conf中指定的動(dòng)態(tài)庫(kù)搜索路徑;

4. 默認(rèn)的動(dòng)態(tài)庫(kù)搜索路徑/lib;

5. 默認(rèn)的動(dòng)態(tài)庫(kù)搜索路徑/usr/lib。


有關(guān)環(huán)境變量:

LIBRARY_PATH環(huán)境變量:指定程序靜態(tài)鏈接庫(kù)文件搜索路徑

LD_LIBRARY_PATH環(huán)境變量:指定程序動(dòng)態(tài)鏈接庫(kù)文件搜索路徑


posted on 2012-02-09 13:43 李陽(yáng) 閱讀(32945) 評(píng)論(7)  編輯 收藏 引用 所屬分類: Linux

評(píng)論:
# re: Linux下Gcc生成和使用靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)詳解(轉(zhuǎn)) 2012-08-01 16:00 |
寫(xiě)的很詳細(xì),謝謝分享!  回復(fù)  更多評(píng)論
  
# re: Linux下Gcc生成和使用靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)詳解(轉(zhuǎn)) 2013-01-15 15:25 | lwVampire
受教了,很細(xì)致的文章  回復(fù)  更多評(píng)論
  
# re: Linux下Gcc生成和使用靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)詳解(轉(zhuǎn)) 2013-03-04 16:49 | zhangmo
非常詳細(xì)的文章,謝謝分享。  回復(fù)  更多評(píng)論
  
# re: Linux下Gcc生成和使用靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)詳解(轉(zhuǎn)) 2013-04-25 15:54 | molixiaoge
謝謝 看了很好  回復(fù)  更多評(píng)論
  
# re: Linux下Gcc生成和使用靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)詳解(轉(zhuǎn)) 2014-05-23 17:20 | zpyws
非常好的文章,受益匪淺  回復(fù)  更多評(píng)論
  
# re: Linux下Gcc生成和使用靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)詳解(轉(zhuǎn)) 2015-01-29 08:27 | lemonsky
寫(xiě)的很好,最近在看embeded compile,這篇文章很有啟發(fā)  回復(fù)  更多評(píng)論
  
# re: Linux下Gcc生成和使用靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)詳解(轉(zhuǎn)) 2016-05-18 18:09 | hdp
gta@gta-virtual-machine:~/Test/gcc$ gcc -shared -fPIC -o libmyhello.so hello.o
/usr/bin/ld: hello.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
hello.o: could not read symbols: Bad value
collect2: ld returned 1 exit status

按照你的方式,在制作動(dòng)態(tài)庫(kù)時(shí)出現(xiàn)了問(wèn)題。
后來(lái)在其他博客中發(fā)現(xiàn)是hello.o的問(wèn)題。
我想問(wèn),是我電腦環(huán)境的問(wèn)題,還是你的博客有問(wèn)題?  回復(fù)  更多評(píng)論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲作爱视频| 欧美日本一道本| 午夜精品久久| 99视频精品在线| 亚洲青涩在线| 99综合精品| 欧美日韩在线亚洲一区蜜芽| 亚洲一区二区在线视频 | 一区二区三区四区国产| 99精品久久| 国产精品试看| 亚洲靠逼com| 亚洲国产日韩欧美在线99 | 欧美国产成人精品| 国产欧美日韩一区二区三区在线观看 | 久久久精品999| 国产午夜精品理论片a级大结局 | 久久久久99| 国内外成人在线视频| 欧美一级久久久| 日韩一区二区电影网| 一区二区三区av| 亚洲精品视频在线看| 激情久久久久久久久久久久久久久久| 亚洲精品一区二区在线观看| 国产日产欧产精品推荐色| 亚洲一区3d动漫同人无遮挡| 国模大胆一区二区三区| 午夜综合激情| 亚洲国产mv| 久久婷婷国产综合精品青草| 在线电影院国产精品| 久久国产天堂福利天堂| 久久精品一区二区三区四区 | 日韩午夜在线电影| 免费成人激情视频| 亚洲国产一二三| 美国十次成人| 洋洋av久久久久久久一区| 黄色成人精品网站| 欧美成人午夜视频| 欧美1区视频| 欧美一区二区三区成人| 亚洲国产精品ⅴa在线观看 | 亚洲人精品午夜在线观看| 亚洲性视频网站| 国产精品人成在线观看免费| 快播亚洲色图| 91久久黄色| 亚洲精品小视频| 亚洲欧洲日本国产| 国产亚洲日本欧美韩国| 久久er精品视频| 久久久久久一区二区| 欧美在线免费播放| 亚洲国产日韩精品| 亚洲电影在线观看| 国产精品久久精品日日| 欧美精品久久99久久在免费线| 欧美大片在线观看一区| 免费成人高清| 免费成人性网站| 亚洲精品一区二区三区婷婷月| 亚洲影院免费| 久久婷婷影院| 先锋影院在线亚洲| 日韩一二三区视频| 午夜激情久久久| 欧美精品日韩www.p站| 欧美视频在线免费看| 国产精品v日韩精品| 国产精品视频最多的网站| 欧美日韩精品久久| 欧美亚州在线观看| 亚洲国产免费看| 亚洲在线一区二区| 亚洲欧美美女| 欧美福利在线| 在线视频日韩精品| 欧美一区国产在线| 国产在线精品二区| 午夜综合激情| 米奇777在线欧美播放| 久久全国免费视频| 欧美一级片一区| 国产亚洲成人一区| 99re这里只有精品6| 亚洲精品极品| 午夜精品久久| 久久久久成人精品| 国外成人在线视频网站| 欧美自拍丝袜亚洲| 亚洲精品永久免费| 欧美裸体一区二区三区| 国产自产在线视频一区| 欧美亚洲在线视频| 中文日韩在线视频| 欧美日韩成人精品| 欧美一级欧美一级在线播放| 亚洲人成在线观看网站高清| 亚洲一区二区欧美日韩| 好吊日精品视频| 欧美激情第8页| 99在线|亚洲一区二区| 日韩午夜在线观看视频| 午夜视频精品| 亚洲国产99精品国自产| 日韩天天综合| 亚洲欧美自拍偷拍| 欧美大片免费观看在线观看网站推荐| 久久九九热re6这里有精品| 一区二区在线视频播放| 欧美一级视频| 亚洲伦理一区| 在线观看欧美视频| 亚洲精品少妇网址| 在线观看欧美成人| 亚洲欧美日韩一区在线| 亚洲一区二区精品在线| 国产日韩欧美视频在线| 香蕉av777xxx色综合一区| 亚洲欧洲在线播放| 国产三级欧美三级日产三级99| 亚洲美女黄网| 在线综合亚洲欧美在线视频| 久久久久久电影| 欧美在线综合| 欧美日韩一区二区三| 夜夜嗨av色综合久久久综合网| 亚洲人午夜精品免费| 久久久久久亚洲精品不卡4k岛国| 国产精品99久久99久久久二8| 久久精品国产免费看久久精品| 亚洲精品之草原avav久久| 亚洲另类一区二区| 亚洲一区二区三区视频播放| 欧美另类99xxxxx| 亚洲精品欧美在线| 亚洲自拍三区| 激情综合亚洲| 久久综合中文字幕| 久久久夜色精品亚洲| 黄色成人在线网站| 米奇777在线欧美播放| 国产精品99久久久久久久女警| 亚洲三级色网| 国产一区二区三区在线观看网站| 亚洲视频一区二区| 亚洲国产一区在线| 欧美在线www| 亚洲免费观看高清完整版在线观看熊 | 亚洲亚洲精品在线观看| 欧美午夜视频在线| av成人老司机| 亚洲在线免费视频| 国内精品久久久久伊人av| 欧美极品欧美精品欧美视频| 亚洲在线一区二区三区| 欧美大片网址| 亚洲国产精品成人一区二区| 一区二区免费在线播放| 国产精品天天看| 欧美理论电影在线观看| 亚洲综合国产| 99精品国产一区二区青青牛奶| 免费成人av资源网| 久久久久久久久综合| 亚洲欧美另类在线观看| 亚洲免费成人av| 99视频精品| 在线视频一区二区| 亚洲国产成人一区| 国产精品一国产精品k频道56| 亚洲美女在线国产| 亚洲精品日韩精品| 亚洲一区尤物| 亚洲线精品一区二区三区八戒| 欧美激情按摩在线| 亚洲欧美日韩一区| 鲁大师成人一区二区三区| 欧美激情国产日韩精品一区18| 欧美日本一区二区三区| 国产午夜精品一区二区三区欧美| 国产美女在线精品免费观看| 国产一二三精品| 国产精品综合网站| 日韩午夜电影av| 欧美中文字幕第一页| 欧美激情一区二区三区| 欧美国产综合一区二区| 亚洲高清在线精品| 夜夜嗨一区二区三区| 麻豆91精品91久久久的内涵| 国产精品日韩欧美一区二区| 国产视频久久久久| 欧美一区中文字幕| 欧美在线观看视频一区二区三区| 久久国产天堂福利天堂| 一区二区三区.www| 国产欧美一区视频|