2010-06-24 113 views
1

這是我在做什麼(這是一個例子,而不是現實生活中的語法):C++靜態庫太大了,爲什麼?

$ svn co http://svn.boost.org/svn/boost/trunk/libs/regex/src regex 
$ c++ -o regex/*.obj -c regex/*.cpp 

我在regex 17個*.obj文件。現在我想從他們創造一個靜態庫:

$ ar -r regex.lib regex/*.obj 

庫的大小是10Mb的。這是一個正確的大小?它應該是隻有17 C++文件的大嗎?我有一個填充,這個庫包含重複的符號。其中許多人..預先感謝一些提示。

+1

看看這個,可能會幫助你:http://stackoverflow.com/questions/3101487/release-mode-static-library-much-larger-than-debug-mode-version – PeterK 2010-06-24 08:46:15

回答

2

您無法從源文件數量預測輸出的大小。一個文件可能包含十幾行簡單的代碼,或者數千行意大利麪,或者一個龐大的數據表。對象文件(和靜態庫,它們只是對象文件的集合)包含用於鏈接的元數據,可以從最終的可執行文件中刪除。如果編譯器被配置爲生成這些信息,它們也可能包含大量的調試信息。你正在建設沒有優化,這通常會膨脹代碼相當多。內聯函數將出現在使用它們的每個對象文件中;鏈接將解決這些重複,但只是將這些對象與ar結合在一起不會。

我剛剛做了同樣的實驗:我得到3.5Mb而不是10Mb開始;添加調試信息(-g)將其增加到8Mb;啓用優化(-O3)將其減小到1.6Mb,與我的計算機上安裝的版本大小相同。我的電腦上安裝的動態庫(使用鏈接器生成,不是ar)仍然較小,大約666kb。

但你爲什麼要擔心圖書館的大小?您是否計劃將產品作爲預編譯的靜態庫進行分發?在軟盤上?您是否試圖在Amiga 500上發展?如果您正在開發一個有限的平臺,那麼擔心最終可執行文件的大小和運行時間足跡。

6

是的,靜態庫往往是相當大的。

原因是他們必須包含來自源文件的所有內容。最終的可執行文件可以去掉它不需要的所有符號,但是在一個靜態庫中,你還不知道哪些符號是需要的,所以一切都必須打包在那裏,通常還有很多調試信息。

這個尺寸不會讓我感到任何異乎尋常的東西。當然,當你將它鏈接到一個可執行文件時,可執行文件的增長將不會那麼快。

5

組成對象文件大小的總和是多少?這幾乎是聚合歸檔的預期大小。由ar添加的元數據應該是最小的。

使用nm實用程序檢查存檔以查看其包含的目標文件和符號。 nm -size-sort開關可能有助於快速找出佔用存檔中最大空間的內容。