庫檔案(動態庫 靜態庫)的編譯及鏈結

2021-10-09 09:44:09 字數 1513 閱讀 5394

庫是寫好的現有的,成熟的,可以復用的**。現實中每個程式都要依賴很多基礎的底層庫,不可能每個人的**都從零開始,因此庫的存在意義非同尋常。本質上來說庫是一種可執行**的二進位制形式,可以被作業系統載入記憶體執行。庫有兩種:靜態庫(.a)和動態庫(.so)。

特點

命名規則

linux靜態庫命名規範,必須是 「lib[your_library_name].a」:lib為字首,中間是靜態庫名,擴充套件名為.a。

例如,建立乙個名為 test 的靜態庫,其命名為 libtest.a。

靜態庫的建立

linux下使用ar指令進行靜態庫操作。

假如有 a.c b.c c.c 三個原始檔,如要將其封裝成乙個靜態庫檔案 libtest.a 具體建立步驟如下:

靜態庫的使用

linux下使用靜態庫,只需要在編譯的時候,指定靜態庫的搜尋路徑(-l選項)、指定靜態庫名(不需要lib字首和.a字尾,-l選項)。

舉例:原始檔 main.c,需要鏈結 libtest.a 靜態庫,生成可執行程式 main,靜態庫在 ./lib 目錄下,其標頭檔案在 ./include 路徑下:

gcc -o main main.c -l./lib -ltest -i./include

多個靜態庫合成乙個靜態庫

有時乙個程式需要鏈結多個靜態庫檔案,比較混亂,需要將多個靜態庫檔案合成乙個靜態庫檔案。

舉例:現有 liba.a libb.a libc.a 三個靜態庫檔案,需要將其合成為 libone.a:

注意:鏈結多個靜態庫時,如果靜態庫之間存在依賴關係,則需要注意編譯順序,底層的靜態庫放在右側,具體原因在後文靜態庫的鏈結順序特點

動態庫與靜態庫區別

動態庫在程式編譯時並不會被連線到目標**中,而是在程式執行是才被載入。不同的應用程式如果呼叫相同的庫,那麼在記憶體裡只需要有乙份該共享庫的例項,規避了空間浪費問題。動態庫在程式執行是才被載入,也解決了靜態庫對程式的更新、部署和發布頁會帶來麻煩。使用者只需要更新動態庫即可,增量更新。

動態庫命名規則

動態庫的建立

與建立靜態庫不同的是,不需要 ar 指令,直接使用編譯器即可建立動態庫。

假如有 a.c b.c c.c 三個原始檔,如要將其封裝成乙個動態庫檔案 libtest.so 具體建立步驟如下:

動態庫的使用

動態庫的使用和靜態庫稍有不同,不同點在於編譯器鏈結動態庫前需要使系統知曉此動態庫的位置,只要動態庫放在 /lib 或者 /usr/lib 路徑下,系統就可找到此動態庫。

舉例:原始檔 main.c,需要鏈結 libtest.so 靜態庫,生成可執行程式 main,動態庫在 ./lib 目錄下,其標頭檔案在 ./include 路徑下,具體步驟如下:

解決方法

方法2:但是在有些大型專案中,依賴關係可能並不容易梳理清楚。此時可以在命令列引數中重複對庫檔案的引用。例如:

gcc -o a.out main.o liba.la libb.la liba.a

編譯靜態庫編譯動態庫

編譯靜態庫 cr標誌告訴ar將object檔案封裝 archive 我們可以使用nm s 命令來檢視.a檔案的內容 ar cr libmyhello.a hello.o 或 cvr 編譯動態庫 gcc c fpic test1.c gcc c fpic test2.c fpic告訴gcc將源 編譯成...

linux下 GCC編譯鏈結靜態庫 動態庫

目錄 回到頂部 有時候需要把一組 編譯成乙個庫,這個庫在很多專案中都要用到,例如libc就是這樣乙個庫,我們在不同的程式中都會用到libc中的庫函式 例如printf 也會用到libc中的變數 例如以後 要講到的environ變數 本文將介紹怎麼建立這樣乙個庫。這些檔案的目錄結構是 tree mai...

動態庫靜態庫編譯鏈結相關問題若干

對於c 編譯鏈結專案依賴什麼的一直不明真相,不過通過遇到過的幾個問題還是增長了一些了解。記錄之。庫分為靜態庫動態庫。動態庫裡面還有一種特別的是執行時有選擇載入的外掛程式,我改cocosbuilder的時候,載入的外掛程式的函式有initwithbundle什麼的,和這個有點兒聯絡。靜態庫是會被編進去...