1. 程式人生 > >linux下的靜態函式庫和動態函式庫

linux下的靜態函式庫和動態函式庫

linux下的靜態庫和動態庫

 

最近在做Linux下應用程式的移植,用到了靜態庫和動態庫概念,從網上搜集了一些資料,並做了簡單整理,轉帖如下:

一、       簡單介紹

inux中有兩類函式庫,分別是靜態庫和動態庫。

1.靜態函式庫:

這類庫的名字一般是libxxx.a;利用靜態函式庫編譯成的檔案比較大,因為整個函式庫的所有資料都會被整合進目的碼中,他的優點就顯而易見了,即編譯後的執行程式不需要外部的函式庫支援,因為所有使用的函式都已經被編譯進去了。當然這也會成為他的缺點,因為如果靜態函式庫改變了,那麼你的程式必須重新編譯。

2.動態函式庫:

這類庫的名字一般是libxxx.so;相對於靜態函式庫,動態函式庫在編譯的時候並沒有被編譯進目的碼中,你的程式執行到相關函式時才呼叫該函式庫裡的相應函式,因此動態函式庫所產生的可執行檔案比較小。由於函式庫沒有被整合進你的程式,而是程式執行時動態的申請並呼叫,所以程式的執行環境中必須提供相應的庫。動態函式庫的改變並不影響你的程式,所以動態函式庫的升級比較方便。

linux系統有幾個重要的目錄存放相應的函式庫,如/lib /usr/lib

二、       初步瞭解靜態庫的建立和使用

下面來介紹

linux靜態函式庫的建立和使用:

 例程str_out.h str_out.c main.c:

str_out.h

#ifndef STR_OUT_H
#define STR_OUT_H
void str_out(const char* str);
#endif

str_out.c

#include
#include “str_out.h”
void str_out(const char* str){
printf(“%s/n”,str);
}

main.c

int main()
{
str_out(“hello world”);
return 0;
}

 

不管是靜態函式庫還是動態函式庫,都是由*.o目標檔案生成。

所以先gcc -c str_out.c

靜態函式庫由ar命令建立

本例:ar -cr libstr_out.a str_out.o

-c create的意思

-r replace的意思,表示當插入的模組名已經在庫中存在,則替換同名的模組。如果若干模組中有一個模組在庫中不存在,ar顯示一個錯誤訊息,並不替換其他同名模組。預設的情況下,新的成員增加在庫的結尾處,可以使用其他任選項來改變增加的位置。

到此靜態函式庫建立完畢。

使用方法:通過gcc -o out main.c -L. -lstr_out編譯main.c就會把靜態函式庫整合進out

其中

-L指定靜態函式庫的位置供查詢,注意L後面還有‘.’,表示靜態函式庫在本目錄下查詢。

-l則指定了靜態函式庫名,由於靜態函式庫的命名方式是lib***.a,其中的lib.a忽略。

根據靜態函式庫的特性,此處刪除libstr_out.aout依然可以執行,因為靜態庫的內容已經整合進去了。

 

三、       初步瞭解動態函式庫的建立和使用

gcc -shared -fPCI -o out main.c -L. -lstr_out

用該命令生成libstr_out.so 動態函式庫。

 gcc -o out main.c

此時還不能立即./out,因為在動態函式庫使用時,會查詢/usr/lib /lib目錄下的動態函式庫,而此時我們生成的庫不在裡邊。

這個時候有好幾種方法可以讓他成功執行:  

最直接最簡單的方法就是把libstr_out.so拉到/usr/lib /lib中去。

還有一種方法 export LD_LIBRARY_PATH=$(pwd)  

另外還可以在/etc/ld.so.conf檔案里加入我們生成的庫的目錄,然後/sbin/ldconfig

/etc/ld.so.conf是非常重要的一個目錄,裡面存放的是連結器和載入器搜尋共享庫時要檢查的目錄,預設是從/usr/lib /lib中讀取的,所以想要順利執行,我們也可以把我們庫的目錄加入到這個檔案中並執行/sbin/ldconfig

另外還有個檔案需要了解/etc/ld.so.cache,裡面儲存了常用的動態函式庫,且會先把他們載入到記憶體中,因為記憶體的訪問速度遠遠大於硬碟的訪問速度,這樣可以提高軟體載入動態函式庫的速度了。

四、例程詳解靜態庫和動態庫的建立和使用

1步:編輯得到舉例的程式–hello.hhello.cmain.c
hello.h(
見程式1)為該函式庫的標頭檔案。
hello.c(
見程式2)是函式庫的源程式,其中包含公用函式hello,該函式將在螢幕上輸出“Hello XXX!”
main.c(
見程式3)測試庫檔案的主程式,在主程式中呼叫了公用函式hello
程式1: hello.h
#ifndef HELLO_H
#define HELLO_H

void hello(const char *name);

#endif //HELLO_H
程式2: hello.c
#include

void hello(const char *name)
{
  printf(“Hello %s!/n”, name);
}
  
程式3: main.c
#include “hello.h”

int main()
{
  hello(“everyone”);
  return 0;
}
2步:將hello.c編譯成.o檔案;
無論靜態庫,還是動態庫,都是由.o檔案建立的。因此,我們必須將源程式hello.c通過gcc先編譯成.o檔案。
在系統提示符下鍵入以下命令得到hello.o檔案。
# gcc -c hello.c
#
(
1:本文不介紹各命令使用和其引數功能,若希望詳細瞭解它們,請參考其他文件。)
(
2:首字元“#”是系統提示符,不需要鍵入,下文相同。)
我們執行ls命令看看是否生存了hello.o檔案。
# ls
hello.c hello.h hello.o main.c
#
(
3:首字元不是“#”為系統執行結果,下文相同。)
ls命令結果中,我們看到了hello.o檔案,本步操作完成。
下面我們先來看看如何建立靜態庫,以及使用它。
3步:由.o檔案建立靜態庫;
靜態庫檔名的命名規範是以lib為字首,緊接著跟靜態庫名,副檔名為.a。例如:我們將建立的靜態庫名為myhello,則靜態庫檔名就是libmyhello.a。在建立和使用靜態庫時,需要注意這點。建立靜態庫用ar命令。
在系統提示符下鍵入以下命令將建立靜態庫檔案libmyhello.a
# ar cr libmyhello.a hello.o
#
我們同樣執行ls命令檢視結果:
# ls
hello.c hello.h hello.o libmyhello.a main.c
#
ls
命令結果中有libmyhello.a
4步:在程式中使用靜態庫;
靜態庫製作完了,如何使用它內部的函式呢?只需要在使用到這些公用函式的源程式中包含這些公用函式的原型宣告,然後在用gcc命令生成目標檔案時指明靜態庫名,gcc將會從靜態庫中將公用函式連線到目標檔案中。注意,gcc會在靜態庫名前加上字首lib,然後追加副檔名.a得到的靜態庫檔名來查詢靜態庫檔案。
在程式3:main.c中,我們包含了靜態庫的標頭檔案hello.h,然後在主程式main中直接呼叫公用函式hello。下面先生成目標程式hello,然後執行hello程式看看結果如何。
# gcc -o hello main.c
-L. -lmyhello
# ./hello
Hello everyone!
#
我們刪除靜態庫檔案試試公用函式hello是否真的連線到目標檔案 hello中了。
# rm libmyhello.a
rm: remove regular file `libmyhello.a’? y
# ./hello
Hello everyone!
#
程式照常執行,靜態庫中的公用函式已經連線到目標檔案中了。
我們繼續看看如何在Linux中建立動態庫。我們還是從.o檔案開始。
5步:由.o檔案建立動態庫檔案;
動態庫檔名命名規範和靜態庫檔名命名規範類似,也是在動態庫名增加字首lib,但其副檔名為.so。例如:我們將建立的動態庫名為myhello,則動態庫檔名就是libmyhello.so。用gcc來建立動態庫。
在系統提示符下鍵入以下命令得到動態庫檔案libmyhello.so
# gcc -shared -fPCI -o libmyhello.so hello.o
#
我們照樣使用ls命令看看動態庫檔案是否生成。
# ls
hello.c hello.h hello.o libmyhello.so main.c
#
6步:在程式中使用動態庫;
在程式中使用動態庫和使用靜態庫完全一樣,也是在使用到這些公用函式的源程式中包含這些公用函式的原型宣告,然後在用gcc命令生成目標檔案時指明動態庫名進行編譯。我們先執行gcc命令生成目標檔案,再執行它看看結果。
# gcc -o hello main.c
-L. -lmyhello
# ./hello
./hello: error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory
#
哦!出錯了。快看看錯誤提示,原來是找不到動態庫檔案libmyhello.so。程式在執行時,會在/usr/lib/lib等目錄中查詢需要的動態庫檔案。若找到,則載入動態庫,否則將提示類似上述錯誤而終止程式執行。我們將檔案libmyhello.so複製到目錄/usr/lib中,再試試。
# mv libmyhello.so /usr/lib
# ./hello
./hello: error while loading shared libraries: /usr/lib/libhello.so: cannot restore segment prot after reloc: Permission denied
由於SELinux引起,
# chcon -t texrel_shlib_t /usr/lib/libhello.so
# ./hello
Hello everyone!
#
成功了。這也進一步說明了動態庫在程式執行時是需要的。
我們回過頭看看,發現使用靜態庫和使用動態庫編譯成目標程式使用的gcc命令完全一樣,那當靜態庫和動態庫同名時,gcc命令會使用哪個庫檔案呢?抱著對問題必究到底的心情,來試試看。
先刪除 .c.h外的 所有檔案,恢復成我們剛剛編輯完舉例程式狀態。
# rm -f hello hello.o /usr/lib/libmyhello.so
# ls
hello.c hello.h main.c
#
在來建立靜態庫檔案libmyhello.a和動態庫檔案libmyhello.so
# gcc -c hello.c
# ar cr 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
#
通過上述最後一條ls命令,可以發現靜態庫檔案libmyhello.a和動態庫檔案libmyhello.so都已經生成,並都在當前目錄中。然後,我們執行gcc命令來使用函式庫myhello生成目標檔案hello,並執行程式 hello
# gcc -o hello main.c -L. -lmyhello
# ./hello
./hello: error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory
#
從程式hello執行的結果中很容易知道,當靜態庫和動態庫同名時, gcc命令將優先使用動態庫。

五、其他問題

1.什麼是庫
windows平臺和linux平臺下都大量存在著庫。
本質上來說庫是一種可執行程式碼的二進位制形式,可以被作業系統載入記憶體執行。
由於windowslinux的本質不同,因此二者庫的二進位制是不相容的。
本文僅限於介紹linux下的庫。
2.庫的種類
linux下的庫有兩種:靜態庫和共享庫(動態庫)。
二者的不同點在於程式碼被載入的時刻不同。
靜態庫的程式碼在編譯過程中已經被載入可執行程式,因此體積較大。
共享庫的程式碼是在可執行程式執行時才載入記憶體的,在編譯過程中僅簡單的引用,因此程式碼體積較小。
3.庫存在的意義
庫是別人寫好的現有的,成熟的,可以複用的程式碼,你可以使用但要記得遵守許可協議。
現實中每個程式都要依賴很多基礎的底層庫,不可能每個人的程式碼都從零開始,因此庫的存在意義非同尋常。
共享庫的好處是,不同的應用程式如果呼叫相同的庫,那麼在記憶體裡只需要有一份該共享庫的例項。
4.庫檔案是如何產生的在linux
靜態庫的字尾是.a,它的產生分兩步
Step 1.
由原始檔編譯生成一堆.o每個.o裡都包含這個編譯單元的符號表
Step 2.ar命令將很多.o轉換成.a,成文靜態庫
動態庫的字尾是.so,它由gcc加特定引數編譯產生。
例如:
gccfPICc.c gcc -shared -Wl,-soname, libfoo.so.1 -o libfoo.so.1.0 *.
5.庫檔案是如何命名的,有沒有什麼規範

linux下,庫檔案一般放在/usr/lib /lib下,
靜態庫的名字一般為libxxxx.a,其中xxxx是該lib的名稱
動態庫的名字一般為libxxxx.so.major.minorxxxx是該lib的名稱,major是主版本號, minor是副版本號
6.如何知道一個可執行程式依賴哪些庫
ldd
命令可以檢視一個可執行程式依賴的共享庫,
例如# 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庫和ld-linux

7.可執行程式在執行的時候如何定位共享庫檔案
當系統載入可執行程式碼時候,能夠知道其所依賴的庫的名字,但是還需要知道絕對路徑
此時就需要系統動態載入器(dynamic linker/loader)
對於elf格式的可執行程式,是由ld-linux.so*來完成的,它先後搜尋elf檔案的 DT_RPATH環境變數LD_LIBRARY_PATH—/etc/ld.so.cache檔案列表—/lib/,/usr/lib目錄找到庫檔案後將其載入記憶體

8.在新安裝一個庫之後如何讓系統能夠找到他
如果安裝在/lib或者/usr/lib下,那麼ld預設能夠找到,無需其他操作。
如果安裝在其他目錄,需要將其新增到/etc/ld.so.cache檔案中,步驟如下
1.
編輯/etc/ld.so.conf檔案,加入庫檔案所在目錄的路徑
2.
執行ldconfig,該命令會重建/etc/ld.so.cache檔案

linux下的靜態庫和動態庫

 

最近在做Linux下應用程式的移植,用到了靜態庫和動態庫概念,從網上搜集了一些資料,並做了簡單整理,轉帖如下:

一、       簡單介紹

inux中有兩類函式庫,分別是靜態庫和動態庫。

1.靜態函式庫:

這類庫的名字一般是libxxx.a;利用靜態函式庫編譯成的檔案比較大,因為整個函式庫的所有資料都會被整合進目的碼中,他的優點就顯而易見了,即編譯後的執行程式不需要外部的函式庫支援,因為所有使用的函式都已經被編譯進去了。當然這也會成為他的缺點,因為如果靜態函式庫改變了,那麼你的程式必須重新編譯。

2.動態函式庫:

這類庫的名字一般是libxxx.so;相對於靜態函式庫,動態函式庫在編譯的時候並沒有被編譯進目的碼中,你的程式執行到相關函式時才呼叫該函式庫裡的相應函式,因此動態函式庫所產生的可執行檔案比較小。由於函式庫沒有被整合進你的程式,而是程式執行時動態的申請並呼叫,所以程式的執行環境中必須提供相應的庫。動態函式庫的改變並不影響你的程式,所以動態函式庫的升級比較方便。

linux系統有幾個重要的目錄存放相應的函式庫,如/lib /usr/lib

二、       初步瞭解靜態庫的建立和使用

下面來介紹linux靜態函式庫的建立和使用:

 例程str_out.h str_out.c main.c:

str_out.h

#ifndef STR_OUT_H
#define STR_OUT_H
void str_out(const char* str);
#endif

str_out.c

#include
#include “str_out.h”
void str_out(const char* str){
printf(“%s/n”,str);
}

main.c

int main()
{
str_out(“hello world”);
return 0;
}

 

不管是靜態函式庫還是動態函式庫,都是由*.o目標檔案生成。

所以先gcc -c str_out.c

靜態函式庫由ar命令建立

本例:ar -cr libstr_out.a str_out.o

-c create的意思

-r replace的意思,表示當插入的模組名已經在庫中存在,則替換同名的模組。如果若干模組中有一個模組在庫中不存在,ar顯示一個錯誤訊息,並不替換其他同名模組。預設的情況下,新的成員增加在庫的結尾處,可以使用其他任選項來改變增加的位置。

到此靜態函式庫建立完畢。

使用方法:通過gcc -o out main.c -L. -lstr_out編譯main.c就會把靜態函式庫整合進out

其中

-L指定靜態函式庫的位置供查詢,注意L後面還有‘.’,表示靜態函式庫在本目錄下查詢。

-l則指定了靜態函式庫名,由於靜態函式庫的命名方式是lib***.a,其中的lib.a忽略。

根據靜態函式庫的特性,此處刪除libstr_out.aout依然可以執行,因為靜態庫的內容已經整合進去了。

 

三、       初步瞭解動態函式庫的建立和使用

gcc -shared -fPCI -o out main.c -L. -lstr_out

用該命令生成libstr_out.so 動態函式庫。

 gcc -o out main.c

此時還不能立即./out,因為在動態函式庫使用時,會查詢/usr/lib /lib目錄下的動態函式庫,而此時我們生成的庫不在裡邊。

這個時候有好幾種方法可以讓他成功執行:  

最直接最簡單的方法就是把libstr_out.so拉到/usr/lib /lib中去。

還有一種方法 export LD_LIBRARY_PATH=$(pwd)  

另外還可以在/etc/ld.so.conf檔案里加入我們生成的庫的目錄,然後/sbin/ldconfig

/etc/ld.so.conf是非常重要的一個目錄,裡面存放的是連結器和載入器搜尋共享庫時要檢查的目錄,預設是從/usr/lib /lib中讀取的,所以想要順利執行,我們也可以把我們庫的目錄加入到這個檔案中並執行/sbin/ldconfig

另外還有個檔案需要了解/etc/ld.so.cache,裡面儲存了常用的動態函式庫,且會先把他們載入到記憶體中,因為記憶體的訪問速度遠遠大於硬碟的訪問速度,這樣可以提高軟體載入動態函式庫的速度了。

四、例程詳解靜態庫和動態庫的建立和使用

1步:編輯得到舉例的程式–hello.hhello.cmain.c
hello.h(
見程式1)為該函式庫的標頭檔案。
hello.c(
見程式2)是函式庫的源程式,其中包含公用函式hello,該函式將在螢幕上輸出“Hello XXX!”
main.c(
見程式3)測試庫檔案的主程式,在主程式中呼叫了公用函式hello
程式1: hello.h
#ifndef HELLO_H
#define HELLO_H

void hello(const char *name);

#endif //HELLO_H
程式2: hello.c
#include

void hello(const char *name)
{
  printf(“Hello %s!/n”, name);
}
  
程式3: main.c
#include “hello.h”

int main()
{
  hello(“everyone”);
  return 0;
}
2步:將hello.c編譯成.o檔案;
無論靜態庫,還是動態庫,都是由.o檔案建立的。因此,我們必須將源程式hello.c通過gcc先編譯成.o檔案。
在系統提示符下鍵入以下命令得到hello.o檔案。
# gcc -c hello.c
#
(
1:本文不介紹各命令使用和其引數功能,若希望詳細瞭解它們,請參考其他文件。)
(
2:首字元“#”是系統提示符,不需要鍵入,下文相同。)
我們執行ls命令看看是否生存了hello.o檔案。
# ls
hello.c hello.h hello.o main.c
#
(
3:首字元不是“#”為系統執行結果,下文相同。)
ls命令結果中,我們看到了hello.o檔案,本步操作完成。
下面我們先來看看如何建立靜態庫,以及使用它。
3步:由.o檔案建立靜態庫;
靜態庫檔名的命名規範是以lib為字首,緊接著跟靜態庫名,副檔名為.a。例如:我們將建立的靜態庫名為myhello,則靜態庫檔名就是libmyhello.a。在建立和使用靜態庫時,需要注意這點。建立靜態庫用ar命令。
在系統提示符下鍵入以下命令將建立靜態庫檔案libmyhello.a
# ar cr libmyhello.a hello.o
#
我們同樣執行ls命令檢視結果:
# ls
hello.c hello.h hello.o libmyhello.a main.c
#
ls
命令結果中有libmyhello.a
4步:在程式中使用靜態庫;
靜態庫製作完了,如何使用它內部的函式呢?只需要在使用到這些公用函式的源程式中包含這些公用函式的原型宣告,然後在用gcc命令生成目標檔案時指明靜態庫名,gcc將會從靜態庫中將公用函式連線到目標檔案中。注意,gcc會在靜態庫名前加上字首lib,然後追加副檔名.a得到的靜態庫檔名來查詢靜態庫檔案。
在程式3:main.c中,我們包含了靜態庫的標頭檔案hello.h,然後在主程式main中直接呼叫公用函式hello。下面先生成目標程式hello,然後執行hello程式看看結果如何。
# gcc -o hello main.c
-L. -lmyhello
# ./hello
Hello everyone!
#
我們刪除靜態庫檔案試試公用函式hello是否真的連線到目標檔案 hello中了。
# rm libmyhello.a
rm: remove regular file `libmyhello.a’? y
# ./hello
Hello everyone!
#
程式照常執行,靜態庫中的公用函式已經連線到目標檔案中了。
我們繼續看看如何在Linux中建立動態庫。我們還是從.o檔案開始。
5步:由.o檔案建立動態庫檔案;
動態庫檔名命名規範和靜態庫檔名命名規範類似,也是在動態庫名增加字首lib,但其副檔名為.so。例如:我們將建立的動態庫名為myhello,則動態庫檔名就是libmyhello.so。用gcc來建立動態庫。
在系統提示符下鍵入以下命令得到動態庫檔案libmyhello.so
# gcc -shared -fPCI -o libmyhello.so hello.o
#
我們照樣使用ls命令看看動態庫檔案是否生成。
# ls
hello.c hello.h hello.o libmyhello.so main.c
#
6步:在程式中使用動態庫;
在程式中使用動態庫和使用靜態庫完全一樣,也是在使用到這些公用函式的源程式中包含這些公用函式的原型宣告,然後在用gcc命令生成目標檔案時指明動態庫名進行編譯。我們先執行gcc命令生成目標檔案,再執行它看看結果。
# gcc -o hello main.c
-L. -lmyhello
# ./hello
./hello: error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory
#
哦!出錯了。快看看錯誤提示,原來是找不到動態庫檔案libmyhello.so。程式在執行時,會在/usr/lib/lib等目錄中查詢需要的動態庫檔案。若找到,則載入動態庫,否則將提示類似上述錯誤而終止程式執行。我們將檔案libmyhello.so複製到目錄/usr/lib中,再試試。
# mv libmyhello.so /usr/lib
# ./hello
./hello: error while loading shared libraries: /usr/lib/libhello.so: cannot restore segment prot after reloc: Permission denied
由於SELinux引起,
# chcon -t texrel_shlib_t /usr/lib/libhello.so
# ./hello
Hello everyone!
#
成功了。這也進一步說明了動態庫在程式執行時是需要的。
我們回過頭看看,發現使用靜態庫和使用動態庫編譯成目標程式使用的gcc命令完全一樣,那當靜態庫和動態庫同名時,gcc命令會使用哪個庫檔案呢?抱著對問題必究到底的心情,來試試看。
先刪除 .c.h外的 所有檔案,恢復成我們剛剛編輯完舉例程式狀態。
# rm -f hello hello.o /usr/lib/libmyhello.so
# ls
hello.c hello.h main.c
#
在來建立靜態庫檔案libmyhello.a和動態庫檔案libmyhello.so
# gcc -c hello.c
# ar cr 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
#
通過上述最後一條ls命令,可以發現靜態庫檔案libmyhello.a和動態庫檔案libmyhello.so都已經生成,並都在當前目錄中。然後,我們執行gcc命令來使用函式庫myhello生成目標檔案hello,並執行程式 hello
# gcc -o hello main.c -L. -lmyhello
# ./hello
./hello: error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory
#
從程式hello執行的結果中很容易知道,當靜態庫和動態庫同名時, gcc命令將優先使用動態庫。

五、其他問題

1.什麼是庫
windows平臺和linux平臺下都大量存在著庫。
本質上來說庫是一種可執行程式碼的二進位制形式,可以被作業系統載入記憶體執行。
由於windowslinux的本質不同,因此二者庫的二進位制是不相容的。
本文僅限於介紹linux下的庫。
2.庫的種類
linux下的庫有兩種:靜態庫和共享庫(動態庫)。
二者的不同點在於程式碼被載入的時刻不同。
靜態庫的程式碼在編譯過程中已經被載入可執行程式,因此體積較大。
共享庫的程式碼是在可執行程式執行時才載入記憶體的,在編譯過程中僅簡單的引用,因此程式碼體積較小。
3.庫存在的意義
庫是別人寫好的現有的,成熟的,可以複用的程式碼,你可以使用但要記得遵守許可協議。
現實中每個程式都要依賴很多基礎的底層庫,不可能每個人的程式碼都從零開始,因此庫的存在意義非同尋常。
共享庫的好處是,不同的應用程式如果呼叫相同的庫,那麼在記憶體裡只需要有一份該共享庫的例項。
4.庫檔案是如何產生的在linux
靜態庫的字尾是.a,它的產生分兩步
Step 1.
由原始檔編譯生成一堆.o每個.o裡都包含這個編譯單元的符號表
Step 2.ar命令將很多.o轉換成.a,成文靜態庫
動態庫的字尾是.so,它由gcc加特定引數編譯產生。
例如:
gccfPICc.c gcc -shared -Wl,-soname, libfoo.so.1 -o libfoo.so.1.0 *.
5.庫檔案是如何命名的,有沒有什麼規範

linux下,庫檔案一般放在/usr/lib /lib下,
靜態庫的名字一般為libxxxx.a,其中xxxx是該lib的名稱
動態庫的名字一般為libxxxx.so.major.minorxxxx是該lib的名稱,major是主版本號, minor是副版本號
6.如何知道一個可執行程式依賴哪些庫
ldd
命令可以檢視一個可執行程式依賴的共享庫,
例如# 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庫和ld-linux

7.可執行程式在執行的時候如何定位共享庫檔案
當系統載入可執行程式碼時候,能夠知道其所依賴的庫的名字,但是還需要知道絕對路徑
此時就需要系統動態載入器(dynamic linker/loader)
對於elf格式的可執行程式,是由ld-linux.so*來完成的,它先後搜尋elf檔案的 DT_RPATH環境變數LD_LIBRARY_PATH—/etc/ld.so.cache檔案列表—/lib/,/usr/lib目錄找到庫檔案後將其載入記憶體

8.在新安裝一個庫之後如何讓系統能夠找到他
如果安裝在/lib或者/usr/lib下,那麼ld預設能夠找到,無需其他操作。
如果安裝在其他目錄,需要將其新增到/etc/ld.so.cache檔案中,步驟如下
1.
編輯/etc/ld.so.conf檔案,加入庫檔案所在目錄的路徑
2.
執行ldconfig,該命令會重建/etc/ld.so.cache檔案