簡體   English   中英

膨脹的EXE大小以及Qt / MingW的有害依賴

[英]Bloated EXE sizes, and unwanted dependencies with Qt/MingW

我試圖找出如何縮小在最新的QT SDK(4.8.2)(基於Mingw / g ++)下編譯的EXE文件的大小。 我正在研究一個具有簡單循環並且僅#includes iostream的香草c ++控制台應用程序,當我注意到它生成的exe約為465kb; 比他們應該的大得多! 注釋掉所有流內容會將其降低到預期的5kb范圍(盡管其余代碼大部分會死掉)。 這似乎一點都不對,尤其是因為我正在處理的另一個完整項目有一個QGLwidget,窗口,十二個數據結構和約3000條語句,而時鍾只有126Kb。 我缺少某些設置或標志嗎? 這是.pro,而cpp則是微不足道且無Qt的(基本上是getline和cout,帶有六個char交換):

TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += main.cpp
QMAKE_CXXFLAGS_RELEASE += -O2
QMAKE_CXXFLAGS_RELEASE += -Os

我嘗試了其他一些配置,並且肯定在發布模式下進行了編譯(調試> 3Mb),但是我不知道為什么它是如此腫。

我還查看了PE標頭,並且看到它從libgcc_s_dw2-1.dll和mingwm10.dll導入了一些函數,如果我也可以完全消除這些依賴關系,那將是一件很不錯的事情,特別是因為兩者都不應該仍然需要。 我可以通過將QMAKE_LFLAGS_RELEASE += -static添加到.pro來使libgcc消失(以exe大小的17kb為代價),但是mingwm10.dll仍然保持不變,調用單個函數。

基於整體膨脹以及編譯器試圖潛入的所有無用框架內容(至少是網絡連接)。 我猜這只是一些歪斜的設置,尤其是一些默認的編譯器標志,例如-DQT_LARGEFILE_SUPPORT或-mthreads。 這是編譯輸出(為強調而添加了項目符號):

  • 14:04:00:項目競爭的運行步驟...
  • 14:04:00:配置保持不變,跳過qmake步驟。
  • 14:04:01:開始:“ C:\\ QtSDK \\ mingw \\ bin \\ mingw32-make.exe”
  • C:/ QtSDK / mingw / bin / mingw32-make -f Makefile。發布
  • mingw32-make [1]:進入目錄C:/ Documents and Settings / Administrator / My Documents / QT / conTest'
  • g ++ -c -O2 -O2 -Os -frtti -fexceptions -mthreads -Wall -DUNICODE -DQT_LARGEFILE_SUPPORT -I“ c:\\ QtSDK \\ Desktop \\ Qt \\ 4.8.1 \\ mingw \\ mkspecs \\ win32-g ++” -o release \\ main .o main.cpp g ++ -Wl,-s -Wl,-子系統,控制台-mthreads -o release \\ conTest.exe release / main.o
  • mingw32-make [1]:離開目錄`C:/ Documents and Settings / Administrator / My Documents / QT / conTest'
  • 14:04:10:進程“ C:\\ QtSDK \\ mingw \\ bin \\ mingw32-make.exe”正常退出。

使用mingw的問題之一是w32版本的binutils不支持死代碼剝離(它刪除了您實際上不使用的部分庫。)為了減小可執行文件的大小,我必須使用以下修補程序從源代碼修補和構建binutils:

http://sourceware.org/bugzilla/show_bug.cgi?id=11539

它有幫助。 但是要使其正常工作,您將需要使用以下命令重建所有內容

-fdata-sections -ffunction-sections

在所有內容(包括GCC,Qt,其他庫您自己的應用程序)的編譯標志中,以及:

-Wl,--gc-sections

僅在應用程序的鏈接標志中。 這對我來說是值得的,因為以前我的可執行文件的大小約為20MB,而現在減少了一半,大約為10MB。 這包括所有庫(我靜態鏈接),包括Qt,SDL和各種媒體庫(如Vorbis,mpg123,FLAC等)。

盡管我想象如果您是在Windows上構建,那么要完成所有這些工作並不容易。 我使用Linux來構建所有東西的w32交叉編譯版本,這很容易。

我會說要添加-s命令。 該命令將剝離所有調試符號的已編譯二進制文件。 通常,當您使用編譯器進行編譯時,它將類和函數的名稱保留在.exe文件中作為查找。 這些符號將包括所有包含的標題。 因此,您的.exe文件將包含iostream符號,包括函數和類。

MinGW具有nm.exe ,可以從cmd執行該命令以列出文件中的所有符號。 strip.exe一起剝離已經創建的符號文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM