2011-06-22 57 views
11

有沒有什麼體面的工具可以在Linux下用g ++來確定最佳靜態鏈接順序?我熟悉一些常見問題,包括(如有必要)使用對單個庫的重複引用或--start-group和--end-group來解決循環依賴問題,但是如果可能的話,是一種工具,它將採用一堆.a文件併爲它們吐出一個良好的靜態鏈接順序,如果需要的話重複庫,同時保持重複到最小。在Linux上尋找一個靜態鏈接訂單工具

背景:我正在研究一個大約800K行繼承的C++代碼的項目,並試圖將其重構爲更小,更易於管理的塊。一些現有的文件是巨大的龐然大物 - 今天我一直在摔跤與一個單一的34K行.h文件,定義113類和結構。許多類在.h文件中幾乎完全內聯定義。當我將它分成更小的塊,並將一些實現代碼遷移到.cpp文件時,Linux上所需的鏈接順序不斷變化。這可能是因爲包含.h文件的每個庫都用於編譯它自己實現的任何所需的類,現在它們必須鏈接到單個庫文件中的通用實現。長期來看,我們可能會將某些類重新組織到不同的庫中,並打破一些依賴關係鏈,但現在依賴關係相當糾結,我試圖最小化代碼中可能改變行爲的擾動。我寧願不必在每次更改時都手動確定正確的鏈接順序。建議?

回答

4

我不知道有一個不在意,但你可以自己實現一個。只需使用nm即可從每個靜態庫中獲取符號列表,使用它來構建依賴關係圖,然後在圖上對適當的鏈接順序執行拓撲排序。

或者,使用部分鏈接(ld -r)而不是靜態庫。由於這會輸出合併的.o文件,因此您的最終鏈接可以按任意順序聲明庫,並且它們都將被正確鏈接。缺點是鏈接器將無法丟棄未使用的源文件,因爲在使用數據可用之前它們已經鏈接到單片文件中(可以在編譯期間通過-ffunction-sections -fdata-sections和最終鏈接上的-Wl,--gc-sections解決此問題,雖然這可能會影響編譯所花費的時間)

+1

我已經想到了,但問題是較麻煩一點。如果您需要在包含之前等待所有打電話給您的人,拓撲排序都可以工作。但這不是必需的:如果圖書館A有一個符號a需要圖書館B的符號b,那麼只要有人以前有人在B的鏈接順序之前,B就可以(事實上,可能有必要)先於A誰也需要的訂單b。我大概可以制定一個合理的算法,但這需要時間,同時還需要完成最後期限的工作。所以我更喜歡經過戰鬥測試的解決方案。 – dewtell

+0

@dewtell:可能有些情況下這種方法不起作用,但您確定您的代碼庫是其中之一嗎? –

+0

@安德魯 - 非常確定。基於.h文件包含,有很多情況下,lib1中的file1a引用lib2中的file2a中定義的符號,而lib2中的file2b引用lib1中file1b中定義的符號。 – dewtell