Linux 如何生成靜態庫和動態庫

2021-07-04 17:46:19 字數 2001 閱讀 4721

1、linux下的庫

靜態庫和共享庫(動態庫),二者的不同點在於**被載入的時刻不同。

靜態庫的**在編譯過程中已經被載入可執行程式,因此體積較大。

共享庫的**是在可執行程式執行時才載入記憶體的,在編譯過程中僅簡單的引用,因此**體積較小。

2、庫存在的意義

庫是別人寫好的現有的,成熟的,可以復用的**,你可以使用但要記得遵守許可協議。

現實中每個程式都要依賴很多基礎的底層庫,不可能每個人的**都從零開始,因此庫的存在意義非同尋常。

共享庫的好處是,不同的應用程式如果呼叫相同的庫,那麼在記憶體裡只需要有乙份該共享庫的例項。

靜態庫的字尾是.a,它的產生分兩步

step 1.由原始檔編譯生成一堆.o,每個.o裡都包含這個編譯單元的符號表

step 2.ar命令將很多.o轉換成.a,成為靜態庫

動態庫的字尾是.so,它由gcc加特定引數編譯產生。具體方法參見後文例項。

在 gnu/linux 系統中靜態鏈結檔案實際上就是多個 .o 檔案的壓縮包。假設我們有 cool.h cool.c 和 some.c 檔案,要得到靜態鏈結庫 libcool.a。首先使用如下指令得到相應的 object 檔案 cool.o 和 some.o:

gcc -c cool.c

gcc -c some.c

ar -r libcool.a cool.o some.o

ranlib libcool.a

靜態鏈結庫 libcool.a 遵從 gnu/linux 規定的靜態鏈結庫命名規範,必須是」libyour_library_name.a」

在 gnu/linux 中動態鏈結檔案,必需通過鏈結器 ld 生成。假設我們有 hot.c other.c 等檔案要生成動態鏈結庫 libhot.so 。首先使用如下指令得到相應的 object 檔案 hot.o 和 some.o

gcc -fpic

-c hot.c

gcc -fpic

-c other.c

引數 -fpic 指定生成的 object 檔案為位置無關**(position-independence code),只有 pic 可以被用作生成動態鏈結庫。然後使用如下指令得到動態庫:

ld -bshared -o libhot.so hot.o other.o
gcc -shared -o libhot.so hot.o other.o
也可以使用編譯器直接生成動態庫:

gcc -fpic -shared -o libhot.so hot.c other.c
這裡選項 -shared 指示目標檔案的型別是動態鏈結庫,動態庫的命名規範是」libyour_library_name.so」

問題一:如何知道乙個可執行程式依賴哪些庫

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庫

問題二:可執行程式在執行的時候如何定位共享庫檔案

當系統載入可執行**時候,能夠知道其所依賴的庫的名字,但是還需要知道絕對路徑。

此時就需要系統動態載入器(dynamic linker/loader)

對於elf格式的可執行程式,是由ld-linux.so*來完成的,它先後搜尋elf檔案的 dt_rpath段—環境變數ld_library_path—/etc/ld.so.cache檔案列表—/lib/,/usr/lib目錄找到庫檔案後將其載入記憶體

如:export ld_library_path=』pwd』

將當前檔案目錄新增為共享目錄

推薦博文位址

Linux 如何生成靜態庫和動態庫

1 linux下的庫 靜態庫和共享庫 動態庫 二者的不同點在於 被載入的時刻不同。靜態庫的 在編譯過程中已經被載入可執行程式,因此體積較大。共享庫的 是在可執行程式執行時才載入記憶體的,在編譯過程中僅簡單的引用,因此 體積較小。2 庫存在的意義 庫是別人寫好的現有的,成熟的,可以復用的 你可以使用但...

如何生成靜態庫和動態庫

對於乙個編譯型語言,編譯器工作時總要經過預處理 編譯 鏈結等幾個過程。以 c c 為例 預處理器 cpp 將每個 c cpp 檔案中 include 的標頭檔案都合併到 c cpp 檔案中,並且對其進行巨集擴充套件,由此生成數個編譯單元。一般來說每個 c cpp 檔案對應乙個編譯單元。隨後,編譯器 ...

如何生成靜態庫和動態庫

對於乙個編譯型語言,編譯器工作時總要經過預處理 編譯 鏈結等幾個過程。以 c c 為例 預處理器 cpp 將每個 c cpp 檔案中 include 的標頭檔案都合併到 c cpp 檔案中,並且對其進行巨集擴充套件,由此生成數個編譯單元。一般來說每個 c cpp 檔案對應乙個編譯單元。隨後,編譯器 ...