2009-11-19 79 views
3

假設我有一個靜態庫libx.a.我如何使這個庫中的一些符號(不是全部)爲總是出現在任何與我的庫的二進制鏈接中?原因是我需要通過dlopen + dlsym使用這些符號。我知道 - 整個存檔鏈接器開關,但它強制從庫存檔的所有目標文件鏈接到生成的二進制文件,這不是我想要的...我如何總是包含來自靜態庫的符號?

到目前爲止的評論(CentOS 5.4,32位)(UPD:本款是錯誤的;我不能重現此問題)

ld main.o libx.a 
我想

將愉快地剝離所有非引用的符號,而

ld main.o -L. -lx 

將鏈接整個圖書館。這取決於binu的版本然而,新的連接器將能夠從靜態庫中挑選單個對象。

另一個問題是如何在Windows下實現相同的效果?

在此先感謝。任何提示將不勝感激。

回答

1

我會先將您始終需要的那些符號拆分爲單獨的庫,只保留libx.a中的可選符號。

+0

似乎是最簡單和最實用的方法,但我相信OP想要一個更優雅的解決方案:) – 2016-02-24 09:58:20

+0

@MottiShneor:簡單實用* *優雅。 ;-)天哪,這必須是我的*最老的* SO帖子之一...... :-D – DevSolar 2016-02-24 10:02:53

+0

我認爲應該有一個鏈接器標誌爲此,類似 - 整體歸檔或類似。我來到這個問題和答案,因爲我現在遭受了相反的問題。我的靜態lib的符號不會「通過」我的Xcode框架(這是一種dylib),我不明白爲什麼。 – 2016-02-26 19:15:36

1

取一個你需要包含的符號地址。

如果gcc的優化器無論如何消除它,做這個地址的東西 - 應該是足夠的。

+0

謝謝,但我已經想到這個黑客;我想知道是否有乾淨的方法來做到這一點。 – kolbusa 2009-11-19 12:51:22

+2

@kolbusa Hacks不會傷害:) – qrdl 2009-11-19 12:57:39

+0

@kolubsa:我不會認爲這是一個黑客...你需要以某種方式引用這些符號來使鏈接器將它們拉入。 – Nicholaz 2009-11-19 13:06:05

2

第一件事第一件事:ld main.o libx.a不構建有效的可執行文件。一般來說,你應該從來沒有使用ld直接鏈接任何東西; 總是改爲使用正確的編譯器驅動程序(本例中爲gcc)。

此外,"ld main.o libx.a""ld main.o -L. -lx"應該完全等效。我非常懷疑你從這兩個命令中得到了不同的結果。

現在回答你的問題:我想包括使用」的符號:如果你想foobarbaz從您a.out出口,這樣做:

gcc -Wl,-u,foo,-u,bar,-u,baz main.o -L. -lx -rdynamic 

更新:
你的聲明由圖書館內部唯一「沒有多大意義:如果符號是圖書館的內部,爲什麼你想要出口它們?如果別的東西使用它們(通過dlsym),那麼它們是而不是內部的庫 - 它們是庫公共API的一部分。

你應該澄清你的問題,並解釋你真的正試圖實現。提供示例代碼也不會傷害。

+0

1.的確,我現在不能再現-l和指定庫之間的區別。也許我那個時候做錯了什麼...... 2.雖然-u看起來像是一個解決方案,但要使用它,我需要在構建二進制文件時知道「額外」符號列表。我想「隱藏」這些依賴關係(我想包含的符號僅由庫在內部使用)。 – kolbusa 2009-11-21 12:35:36

3

想象一下,您有一個項目由同一文件夾中的以下三個C文件組成;

// ---- jam.h 
int jam_badger(int); 

// ---- jam.c 
#include "jam.h" 
int jam_badger(int a) 
{ 
    return a + 1; 
} 

// ---- main.c 
#include "jam.h" 
int main() 
{ 
    return jam_badger(2); 
} 

然後你用這樣的boost-build bjam文件構建它;

lib jam : jam.c <link>static ; 

lib jam_badger : jam ; 

exe demo : jam_badger main.c ; 

你會得到這樣的錯誤。

undefined reference to `jam_badger' 

(我用的bjam這裏,因爲文件更容易閱讀,但你可以使用任何你想要的)

去掉「靜態」產生一個工作的二進制一樣,添加靜態其他庫,或者只是使用一個庫(而不是在另一個裏面的愚蠢包裝)

發生這種情況的原因是因爲ld足夠聰明,只選擇實際使用的歸檔部分,在這種情況下是他們中的任何一個。

解決方案是用-Wl, - whole-archive和-Wl, - no-whole-archive等環繞靜態存檔,就像這樣;

g++ -o "libjam_candle_badger.so" -Wl,--whole-archive libjam_badger.a Wl,--no-whole-archive 

不太確定如何獲得助推 - 構建爲你做到這一點,但你明白了。

+0

您是否有機會了解如何通過Apple Xcode構建設置來實現這一點? Xcode爲自己構建命令行。使用它的「構建設置」窗體,你可以修改它的工作方式,從而間接引入鏈接器標誌,再加上你自己的「其他鏈接器標誌」,但我認爲他們不會「環繞」一個特定的輸入文件/ staticLib。 – 2016-02-24 10:04:01

相關問題