linux動態庫與靜態庫

2021-08-15 19:47:20 字數 3757 閱讀 4524

​ ​ 現實中每個程式都要依賴很多基礎的底層庫,不可能每個人的**都從零開始。盡量不重複做別人已經做過的事,「站在巨人的肩膀上」做事情。

​ 根據鏈結時期的不同,庫又有:靜態庫和共享庫(動態庫)。

​ 二者的不同點在於**被載入的時刻不同, 靜態庫的**在編譯過程中已經被載入可執行程式,因此體積較大。共享庫的**是在可執行程式執行時才載入記憶體的,在編譯過程中僅簡單的引用,因此**體積較小。

​ 一般gcc在編譯的時候預設使用動態庫,可以直接新增-static強制使用靜態庫。

​ 靜態庫的名字一般是lib***.a(linux).

​ 動態庫的名字一般是lib***.so(linux),有時候也是 lib***.so.major.minor,***x是該lib的名稱,major是主版本號, minor是副版本號。

​ 1 file命令

​ file程式是用來判斷檔案型別的,並且可以檢視檔案是否使用了動態庫。

where@ubuntu:~$ file /bin/ls

/bin/ls: elf 32

-bit lsb executable, intel 80386, version 1 (sysv), dynamically linked (uses shared libs), for gnu/linux 2.6.24, buildid[sha1]=de9c5af34773e23cf554e0da78320e76a3b85120, stripped

2 ldd命令

​ ​ ldd是英文list dynamic dependencies的縮寫,用來檢視動態庫,如果目標程式沒有鏈結動態庫,則列印「not a dynamic executable」 (不是動態可執行檔案)

where@ubuntu:~$ ldd /bin/ls

linux-gate.so.1 => (0xb7765000)

libselinux.so.1 => /lib/i386-linux-gnu/libselinux.so.1 (0xb772a000)

libacl.so.1 => /lib/i386-linux-gnu/libacl.so.1 (0xb7721000)

libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7572000)

libpcre.so.3 => /lib/i386-linux-gnu/libpcre.so.3 (0xb7534000)

libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0xb752f000)

/lib/ld-linux.so.2 (0x800d3000)

libattr.so.1 => /lib/i386-linux-gnu/libattr.so.1 (0xb7529000)

3 編譯動態庫

#ifndef __mylib_h__

#define __mylib_h__

inttest();

#endif

#include 

#include "mylib.h"

inttest()

gcc

-fpic

-c mylib.c

​ -fpic 作用於編譯階段,告訴編譯器產生與位置無關**(position-independent code),  則產生的**中,沒有絕對位址,全部使用相對位址,故而**可以被載入器載入到記憶體的任意  位置,都可以正確的執行。這正是共享庫所要求的,共享庫被載入時,在記憶體的位置不是固定的。

gcc

-shared mylib.o -o libmy.so

gcc

-shared

-fpic mylib.c -o libmy.so

4 呼叫動態庫

#include "mylib.h"

intmain()

gcc

-o test test.c libmy.so

gcc

-o test test.c -l./ -lmy

export

library_path

=$library_path/homw/where/lib   #/home/where為我當前庫路徑

gcc-o test test.c -lmy

mv libmy.so /usr/lib #或者 /lib /usr/local/lib 

gcc-o test test.c -lmy

gcc預設查詢動態的順序:

1、-l引數指定的路徑

​2、library_path環境變數指明庫搜尋路徑

​3、gcc內定庫/lib、/usr/lib、/usr/local/lib

5 標頭檔案引用

gcc test.c -o test -lmy

gcc test.c

-o test -i./

export

c_include_path

=$c_include_path:/home/where/lib

gcc test.c -o test

1、當前編譯路徑

2、-i 指定的路徑

3、c_include_path,cplus_include_path環境變數等路徑

4、再找系統內定目錄如/usr/include、/usr/local/include

6執行時庫查詢

1、在配置檔案/etc/ld.so.conf中指定動態庫搜尋路徑

sudo

vi /etc/ld.so.conf.d/mylib.conf #新建mylib.conf寫入你自己的庫路徑,如/home/where/lib

sudo ldconfig

#更新一下快取才能生效

2、通過環境變數ld_library_path指定動態庫搜尋路徑

export

ld_library_path

=$ld_library_path:/home/where/lib

3、預設的動態庫搜尋路徑/lib、/usr/lib

7 編譯靜態庫

#ifndef __mylib_h__

#define __mylib_h__

inttest();

#endif

#include 

#include "test.h"

inttest()

gcc

-c mylib.c

ar rcs libmy.a mylib.o
引數r:#在庫中插入模組(替換)。當插入的模組名已經在庫中存在,則替換同名的模組。如果若干模組中有乙個模組在庫中不存在,ar顯示乙個錯誤訊息,並不替換其他同名模組。預設的情況下,新的成員增加在庫的結尾處,可以使用其他任選項來改變增加的位置。

引數c:#建立乙個庫。不管庫是否存在,都將建立。

引數s:#建立目標檔案索引,這在建立較大的庫時能加快時間。

8 呼叫靜態庫

gcc

-o test test.c libmy.a

gcc

-o test test.c -l. -lmy

gcc

-o test test.c -l. -lmy

-static

Linux靜態庫與動態庫

靜態庫 a 靜態庫的 在編譯過程中已經被載入可執行程式,因此體積較大。編譯程式時候需要庫作依賴,執行時候不需要。方便,不再需要外部函式庫支援 缺點 1 因為靜態庫被鏈結後直接嵌入可執行程式中,相當於每乙個可執行程式裡都有乙個庫的副本,浪費空間 2 一旦庫中有bug,需要重新編譯。建立步驟 1 編寫函...

Linux 靜態庫與動態(共享)庫

不論是在linux還是windows下程式設計,我們都會用到庫,有自身帶的標準庫,也有我們自己寫的庫,庫就是預先編譯好的的方法的集合。linux中的庫可以分為兩種,靜態庫和動態庫,動態庫也稱為共享庫。在linux中,庫名稱都以lib開始,靜態庫名為 lib a,動態庫名為 lib so。靜態庫和動態...

Linux中靜態庫與動態庫

在windows和linux下都存在著大量的庫,庫是什麼呢?本質上來說,庫時一種可執行 的二進位制形式,可以被作業系統載入記憶體執行。我們通常將一些公用函式寫成函式庫,所以庫是別人寫好的,現有的,成熟的,可以服用的 你可以使用但要必須得遵守許可協議。在我們現實開發過程中,不可能每乙份 都從頭編寫,當...