動態庫 so 鏈結靜態庫 a 的情況總結

2021-07-27 17:19:11 字數 2748 閱讀 1387

來自:

動態庫(.so)鏈結靜態庫(.a)的情況總結 

1、link時加上 -static 選項;當加上 -static選項後,gcc會把所有用到的庫都做靜態連線。

2、link時直接指定想要靜態連線的.a檔案的絕對路徑。優點是除非.a檔案不存在,否則肯定有效;缺點也是很明顯,拿到其他機器上編譯時,.a檔案也必須在相同的路徑下存放。

3、在要靜態連線的庫前指定-bstatic ,在要動態連線的庫前指定-bdynamic選項。聯結器在看到-bstatic時會優於去找靜態庫,如果找不到再去找動態庫。 -bdynamic也是同樣的情況。(

可是我實驗的結果是這兩個選項根本不起作用,我的環境是centos 6.2 gcc4.7.2, 仔細看了gcc 文件,這兩個選項是針對vxworks平台的,所以不起作用。)

當我們要編譯乙個so提供給外部使用,這個so本身依賴一些第三方庫。但是我們卻希望so的使用者不用關心該so對其他庫的依賴。很自然的是會想到在編譯so的時候把依賴到的第三方庫靜態鏈結進來。

我在這樣做的時候碰到了問題:指定-static選項時,link失敗,錯誤提示說要用到的object檔案應該用-fpic選項重新編譯才行(也就是說,只有用-fpic選項編譯的object檔案能被link到.so裡);當直接給出.a的絕對路徑的時候link成功,但是.so裡卻並沒有直正包含所用到的符合連線。針對碰到的問題,我做了一些實驗。實驗如下:

static.c

#include

const char* sz_static = "i'm a static str.";

void print_niuzai_said()

dynamic.c

#include

#include "static.h"

void print_papa_said()

main.c

#include

#include "dynamic.h"

int main(int argc, char** argv)

分別用兩組命令編譯出了兩個.a 檔案

1、gcc -o static.o -c static.c

ar -r libstatic.a static.o

2、gcc -o static_shared.o -shared -fpic -c static.c

ar -r libstatic_shared.a static_shared.o

然後用此命令  "gcc -o dynamic.o -c dynamic.c"  編譯出dynamic.o檔案

1、使用 "gcc -o libdynamic.so -shared -fpic -l. -lstatic dynamic.o ",連線成功,但.so裡實際上沒有static.o裡的內容。

2、使用"gcc -o libdynamic.so dynamic.o -shared -fpic -l. -lstatic",連線失敗

3、使用 "gcc -o libdynamic.so -shared -fpic -l. -lstatic_shared dynamic.o",連線成功,但.so裡實際上沒有static.o裡還是沒有的內容。

4、使用 "gcc -o libdynamic.so dynamic.o -shared -fpic -l. -lstatic_shared",連線成功,.a的內容被連線到了.so裡面。

另外,鏈結靜態生成可執行程式時,靜態庫是不是用 "-shared -fpic" 選項編譯產生的沒有影響。都能正常生成可執行程式。

綜合以上情況,總結如下:

1、動態連線庫中用到的object檔案必須是用 "-shared -fpic"選項編譯產生的,否則連線時要麼報錯,要麼被忽略。

2、靜態庫中的object檔案最好也用"-shared -fpic"選項編譯,這樣靜態庫就可以同時被連線到.so 或者可執行性檔案中。

3、動態庫只能連線用"-shared -fpic"選項編譯出來的靜態庫(和第1點是同一件事)

4、連線選項的順序對聯結器的行為有重要影響!

靜態庫使用-shared -fpic

連線命令

連線執行結果

動態庫結果

最終結果

否gcc -o libdynamic.so -shared -fpic -l. -lstatic dynamic.o

成功靜態庫內容沒有被連線失敗否

gcc -o libdynamic.so dynamic.o -shared -fpic -l. -lstatic

失敗失敗

是gcc -o libdynamic.so -shared -fpic -l. -lstatic_shared dynamic.o

成功靜態庫內容沒有被連線失敗是

gcc -o libdynamic.so dynamic.o -shared -fpic -l. -lstatic_shared

成功靜態庫內容被連線成功

編譯鏈結動態庫 so

有兩種方法 1.比較方便,用命令列進行鏈結 arm linux gnueabihf g main.cpp psencodercontrol.h l.lpsencodercontrol o test上面是乙個例子,鏈結動態庫.so時候要用到 l.l 命令,l後面加上你的庫,加庫名字時候要把前面的lib...

靜態庫,靜態鏈結,動態鏈結 的區別

遺憾地說 除了ender說的 靜態庫在程式執行時就會裝入記憶體,而動態庫在呼叫的時候才裝入!是正確的外,其他觀點都有偏頗之處甚至是錯誤的。我的感覺是,大家受mfc的影響太深了,而沒有看到事情的本質。首先糾正所謂 靜態連線就是把需要的庫函式放進你的exe之中 的說法。在真實世界中,有三個概念 use ...

Linux下動態庫 so 和靜態庫 a

一般情況下,在專案裡會把功能相似的 封裝成庫,方便使用和管理,同時增加了 的內聚性。庫分為兩種,一種為靜態庫,檔名以.a結尾,另一種是動態庫,檔名以.so結尾。靜態庫和動態庫的使用各有利弊。靜態庫的特點 動態庫的特點 現在用乙個微型的工程,來講述靜態庫 動態庫的生成和使用。假設有3個.c檔案,分別為...