5

最新の QT SDK (4.8.2) (mingw/g++ ベース) でコンパイルされた EXE ファイルのサイズを縮小する方法を見つけようとしています。私は単純なループを持ち、#includes iostream のみを含むバニラ C++ コンソール アプリで作業していましたが、生成された exe が約 465kb であることに気付きました。彼らが本来あるべきよりもはるかに大きい!すべてのストリームをコメント アウトすると、予想される 5kb の範囲になります (ただし、残りのコードはほとんど役に立ちません)。特に、私が取り組んでいる別の完全なプロジェクトには、QGLwidget、ウィンドウ処理、ダースのデータ構造、および約 3000 のステートメントがあり、約 126Kb でクロックインするだけなので、これはまったく正しくないようです。不足している設定やフラグはありますか? これが.proですが、cppは簡単でQtフリーです(基本的には、半ダースの文字スワップを使用したgetlineとcout):

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 からいくつかの関数をインポートしていることがわかります。これらの依存関係も完全に排除できればいいのですが、特にどちらもそうすべきではないためです。とにかく必要です。.pro に追加することで libgcc をなくすことができます (17kb の exe サイズを犠牲にして)QMAKE_LFLAGS_RELEASE += -staticが、mingwm10.dll はどちらの方法でも残り、単一の関数を呼び出します。

全体的な肥大化と、コンパイラーが忍び込もうとしているすべての役に立たないフレームワークのもの (少なくともネットワーク) に基づいています。特に -DQT_LARGEFILE_SUPPORT や -mthreads などのデフォルトのコンパイラ フラグのいくつかでは、いくつかの設定が歪んでいるだけの問題だと思います。コンパイル出力は次のとおりです (強調のために箇条書きが追加されています)。

  • 14:04:00: プロジェクト conTest のステップを実行しています...
  • 14:04:00: 構成は変更されていません。qmake ステップをスキップしています。
  • 14:04:01: 開始: "C:\QtSDK\mingw\bin\mingw32-make.exe"
  • C:/QtSDK/mingw/bin/mingw32-make -f Makefile.Release
  • 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,-subsystem,console -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」が正常に終了しました。
4

2 に答える 2

3

mingw を使用する際の問題の 1 つは、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 クロスコンパイル バージョンをビルドしました。

于 2013-03-03T18:50:42.477 に答える
2

-sコマンドに追加するといいでしょう。このコマンドは、コンパイルされたバイナリ ファイルからすべてのデバッグ シンボルを取り除きます。通常、コンパイラで何かをコンパイルすると、クラスと関数の名前がルックアップとして .exe ファイルに残ります。これらのシンボルには、含まれているすべてのヘッダーが含まれます。したがって、.exe ファイルにはiostream、関数やクラスを含む のシンボルが含まれます。

MinGW にはnm.exe、ファイル内のすべてのシンボルを一覧表示するために cmd から実行できるものがあります。とともに、strip.exe既に作成されたファイルのシンボルを削除します。

于 2013-03-03T18:27:08.550 に答える