2015-07-11 126 views
-2

通過只選擇需要的功能並消除不必要的文件,減少庫大小的更簡單的方法是什麼? 是否有一個腳本來完成C++庫的這項任務?C++通過編程排除不必要的函數來減少庫大小?

+0

鏈接器通常會嘗試自動檢測哪些函數或至少文件可到達並刪除不需要的函數。查看你的手冊,看看如何設置。請注意,不必要地拖動事物仍然很容易,如果大小是一個問題,那麼您應該偶爾瀏覽一下地圖文件以查看實際正在發生的事情。函數指針/工廠等等的表是頻繁的罪魁禍首,並且正好注意從動態鏈接庫導出的內容。 – doynax

+1

**爲什麼**你問?什麼情況下想縮小圖書館的規模?通常這並不重要,因爲圖書館是共享的!請**編輯您的問題**以改進它,給出您的動機,上下文,使用什麼編譯器,操作系統,優化標記,實際庫是什麼等等。 –

+0

爲什麼?鏈接程序不鏈接任何不可訪問的庫。你想解決什麼問題? – EJP

回答

0

如果你不想做一個圖書館重構(假設你有權訪問源代碼,但並不總是一個現實的假設),就是把它作爲靜態庫鏈接起來,或者作爲應用程序的一部分進行編譯:所有編譯器將從中受益。

請注意,與其他編譯器相比,Clang在靜態鏈接時能夠進行大量優化,具有非凡的行爲。

如果您因爲某種原因必須使用DLL,您可以嘗試調整導出符號的可見性(您可以隱藏客戶端代碼中不可見的符號並僅導出使用的符號):請注意,這可能會啓用某些優化考慮速度和二進制大小,但可能是一項單調乏味的工作(我認爲它是一個重大的重構,因爲它有可能破壞事物)。

如果你使用的是依賴注入容器,你可能會測試它們來警告未使用的依賴關係,這樣你就可以很容易地將它們連接起來,而不需要接觸源代碼(你對容器做了一些重構,但不是整體的重構代碼庫),除了組合根中的源代碼。

+0

海灣合作委員會也能夠做LTO。 –

+0

是的,但是以不同的方式: GCC: https://gcc.gnu.org/wiki/LinkTimeOptimization 鏘: http://llvm.org/docs/LinkTimeOptimization.html 它不轉儲一些內部狀態(實際上可能更多的是實現細節,而不是相關的東西)我並不是說GCC沒有優化(實際上仍然更喜歡GCC) – GameDeveloper

1

在典型的C++應用程序中,模板代表了大部分功能(例如,STL vectorstring等)。這些函數只能在使用時生成爲代碼(儘管它們可能會作爲內聯函數生成,在某些情況下,這些函數可能導致大代碼)。

鏈接器只會「挑選」您的應用程序所需的代碼(當然包括您使用的函數調用的函數)。然而,例如Linux上的基本運行時間非常大,因爲它調用了很多功能,而這些功能又反過來使用了其他功能的一小部分 - 所以您的基本可執行文件的大小非常大。在典型情況下,添加更多自己的代碼不會增加相當大的數量。

如果大小很重要,那麼使用「小型C++庫」也許是一種選擇 - 這些庫可用於不同的操作系統。編譯器使用-Os等選項告訴它「使代碼變小」(換句話說,不要內聯函數,除非通過內聯比代碼縮短而不是調用函數,並且不要展開循環等,等等 - 但只能調用一次內聯函數,因爲這樣做會使代碼更短)

+0

爲什麼大家都認爲他在使用GCC,他甚至沒有提到編譯器。據我們所知,他可以使用視覺工作室至少生成幾MB的靜態庫,甚至幾行代碼,除非你玩編譯器選項 – GameDeveloper

+0

我沒有這樣的假設。 gcc,clang或visual studio的鏈接程序幾乎完全相同,並且都使用「-Os」(和armcc一樣)「優化小尺寸」。即使是我30年前使用的Atari ST編譯器/鏈接器也只能包含實際使用的函數,所以我懷疑自從DOES NOT以來生成的任何其他編譯器...... –

2

您可能應該先嚐試設置編譯以最小化大小。而回答你的問題取決於編譯器,鏈接器,什麼操作系統,優化的標誌,等了很多...

隨着近來GCC編譯器(g++)在Linux上,你應該嘗試編譯和鏈接-Os)和link time optimization-flto)。

所以把

CXX=g++ -flto -Os 

靠近你Makefile或只需運行make CXX='g++ -flto -Os'開始後一個make clean

BTW,Clang/LLVM也知道-flto(和使用GOLD像GCC一樣)

公告共享library(或者可能是微軟世界中的一個DLL)需要包含所有的代碼(正是因爲它是共享的下注幾個過程和程序)。您可能會靜態鏈接您的庫(然後在構建靜態庫時以及將它鏈接到主程序時使用g++ -flto -Os

很多時候,共享庫比嘗試減少它們的空間更有價值。

如果在Linux上,請閱讀program library howto

+0

不知道-flto選項,我會嘗試向Cmake開發者發出一個功能請求來支持它。 – GameDeveloper

+0

LTO的'cmake'已經支持。您可以簡單地嘗試'make clean'然後'make CXX ='g ++ -flto -Os'' –

+0

這需要對GCC進行手動干預,我的意思是CMake已經自動使用某些編譯器標誌(例如用於Release版本中的GCC使用'-O3 ')你是否確實聲稱'-flto'會自動與一些構建配置一起使用,而不需要用戶手動指定一個標誌? (擁有這種自動性會很好,因爲你得到一個免費的優化,而實際上不必爲GCC維護一個單獨的標誌,當你編譯一個庫時,對於3個不同的編譯器和10個編譯器版本,有很多依賴關係是很好的)。手動指定標誌是衆所周知的cmake反模式 – GameDeveloper

相關問題