2010-04-09 111 views
9

爲了一個理由,我想將一個靜態lib(libx.a)解壓到單個目標文件(ao bo co)中,並在鏈接器輸入中指定這些目標文件(ao bo co)列表而不是libx.a,其他鏈接器選項保持不變。鏈接靜態庫vs單個目標文件

但是,我注意到上述變化導致了輸出可執行文件中的一些不同。基本上,(a.o b.o c.o)方法將導致更大的輸出尺寸。

那麼兩種方法(libx.a和單個對象文件)之間有什麼區別? 有沒有辦法解決?

的GNU binutil我使用(並AR LD)的版本是2.16.1

感謝。

+0

這是什麼,你試圖通過拆分單個目標文件來完成? – 2010-04-10 03:20:58

+0

最初的原因是,我想在鏈接器腳本中爲靜態庫指定輸出節。由於某種原因,歸檔語法(libx.a:* .o(.text))不起作用,可能是由於我的工具鏈中存在過時的binutil版本。由於我無法升級工具鏈,因此我必須解壓縮庫並使用對象文件的明確性。這就是我遇到這個問題的原因。 – user313031 2010-04-18 06:20:40

回答

10

Ld刪除鏈接的.lib存檔的未使用部分(如具有全局鏈接的變量)。這種優化不能在直接傳遞對象文件時發生,因爲鏈接器無法確定稍後某個未知部分是否需要某個.o文件的某個未引用元素(例如,因爲它將由模塊導出列表進行外部可見)或可以完全刪除。當在鏈接過程中放置​​.lib時,鏈接器確切知道它可以刪除不必要的元素。

+0

我不懷疑你所說的是真實的,但它必須具體說明ld的問題。據我所見,只要你在最後一步的鏈接上,ld應該能夠使用.o文件去除與使用.a文件一樣的所有相同的死代碼。 – 2010-04-10 03:20:23

+0

.lib和.o文件之間的區別在於,ld將.lib文件中未引用的.o文件視爲可丟棄文件,而每個.o文件都包含在輸出中。這是因爲存在特殊的符號(例如C++構造函數),它們被ld分組成特殊的部分(即使它們未被引用時)以執行特殊的功能。還有一個開關(--whole-archive)可以從.lib文件中實例化每個未引用的.o文件,但是我不知道是否有一個開關可以刪除無需要的.o文件。 – Rudi 2010-04-10 10:11:31

+0

謝謝大家。很高興知道這一點。 但這是否意味着如果我在鏈接最終可執行文件之前總是將單個目標文件鏈接到一個靜態庫中,那麼我可能會得到較小的輸出(如果有未引用的代碼/數據)?如果那是真的,它可能是一種有用的技術(雖然聽起來反直覺)。 並回到我原來的問題(無法指定鏈接器腳本中的靜態庫的輸出部分),有沒有辦法解決? 謝謝。 – user313031 2010-04-18 06:28:55