2011-05-04 47 views
5

我正在編譯一個主要包含模板類的靜態庫。當使用gcc進行編譯時,生成的.a文件大約在40Mb左右。這是相當大的,但並不完全出乎意料,因爲大量的模板正在進行。但是,當我使用VS2005編譯相同的代碼時,生成的.lib文件進入(等待它!)575Mb ..使用VS2005編譯時,巨大的靜態庫文件,使用gcc編譯時的正常大小

現在,在我被燒燬之前,我已經看到:How can I get my very large program to link?,這對於瞭解模板可能會使庫很大,但我很難理解爲什麼兩個編譯器的輸出在大小上如此不同?

VS選項有: (調試)

/Od /D "WIN32" /D "_DEBUG" /D "_LIB" /D "_WIN32_WINNT=0x0500" /D "_MBCS" /Gm /EHsc /RTC1 /MDd /W4 /nologo /c /Wp64 /Zi /TP /errorReport:prompt 

(釋放)

/O2 /D "WIN32" /D "NDEBUG" /D "_LIB" /D "_WIN32_WINNT=0x0500" /D "_MBCS" /FD /EHsc /MD /W4 /nologo /c /Wp64 /Zi /TP /errorReport:prompt 

任何意見或指針大加讚賞..

+0

您正在VS2005上構建一個Debug版本('/ D「_DEBUG」') - 這和GCC一樣嗎?這可能會造成相當大的差異。 – 2011-05-04 14:51:01

+0

你是對的,它確實.. VS2005上的發佈版本是*僅* 350Mb ..儘管如此,仍然沒有足夠小! – StevieG 2011-05-04 14:54:27

+0

您正在使用Linktime代碼生成(LTCG)嗎?這使靜態庫非常大,然後優化器在鏈接時縮減最終代碼。 – 2011-05-04 14:59:26

回答

3

調試版本禁用內聯和也鏈接器選項,丟棄重複的代碼,所以你會得到大量的每個模板和內聯函數的副本。

您可以在鏈接器選項中使用/OPT:REF /OPT:ICF啓用它。但是它應該在發佈版本中默認使用。

不幸的是,我認爲這隻對最終的可執行文件有幫助,而不是中間庫。

您可以通過在一個.cpp中顯式實例化您需要的模板實例並使用extern template來防止在編譯其他源文件時自動實例化,從而節省一些空間。

+0

是的,我很肯定按照這些思路來減少一般的尺寸..但仍然無法讓我的腦海爲什麼它在gcc中更好,沒有任何明確的實例化或其他編碼優化... – StevieG 2011-05-04 16:06:48

+0

我也是。我想知道它是否涉及功能級別的鏈接(/ Gy,暗示爲/ O2)。這是一個很好的優化,但它必須增加目標文件的開銷 - 特別是如果您有很多重複生成的小內聯函數。你可以嘗試指定/ Gy-在發佈模式,看看它是否有任何區別。 – 2011-05-04 20:00:31

+0

接受這個答案是最有用的,儘管問題仍然存在。 – StevieG 2012-02-10 12:39:52