我正在使用 wxDev-C++ IDE(在 windows 7 中)创建一个简单的(hello world!)C++ 应用程序,它有一个非常简单的 GUI(只有一个没有元素的框架)。
问题是输出 .exe 文件的大小太大(当我使用 MSVC10 编译器编译时大约为 2MB,当我使用 GCC 编译时超过 8MB,这些大小是最好的情况!)。
我检查了许多可能性(例如排除调试信息或优化大小),但没有一个对减小可执行文件大小没有帮助。
我强烈猜测存在链接问题,因为我见过一个演示应用程序,其中包含几乎所有小部件,代码大小只有大约 1MB。
任何想法?
2 回答
以下是使用 mingw 减小静态链接的 wxWidgets 应用程序大小所需遵循的步骤:
1.使用以下选项编译库:
-ffunction-sections -fdata-sections -Os
这会将每个函数或数据项放入其自己的部分。
2.使用以下选项将可执行文件链接到库:
-Wl,--gc-sections -s
符号和未使用的功能和数据部分将被删除。
使用这些选项,生成的可执行文件大小约为 3.3 MB。当然,这意味着您必须自己编译库,而不是使用预构建的二进制文件。我使用了以下 bat 文件来编译库:
cd C:\wxWidgets\build\msw
mingw32-make SHELL=CMD.exe -j4 -f makefile.gcc BUILD=release UNICODE=1 SHARED=0 clean
mingw32-make SHELL=CMD.exe -j4 -f makefile.gcc CPPFLAGS="-MD -MP -DHAVE_W32API_H -D__WXMSW__ -DNOPCH -DwxDEBUG_LEVEL=0 -DNDEBUG" CFLAGS="-mthreads -pipe -fmessage-length=0 -ffunction-sections -fdata-sections -fno-builtin -Os" CXXFLAGS="-mthreads -Wno-ctor-dtor-privacy -pipe -fmessage-length=0 -ffunction-sections -fdata-sections -fno-builtin -Os" LDFLAGS="-Wl,--subsystem,windows -Wl,--gc-sections -s -mthreads -mwindows" BUILD=release UNICODE=1 SHARED=0
我还建议您使用 code::block 或 Qt Creator 而不是 wxDev。我个人使用 Qt Creator。它有一个很棒的编辑器,QMake 让事情变得更容易。
当您将全部内容打包到一个 exe 文件中时,您期望什么?(静止的)
编译的 .exe 文件的大小基于许多因素。但是,如果您将其编译为静态,您将创建迄今为止最大的。
例如,这是一个 wxWidgets 应用程序。编译了两次。一个使用 VC2010,第二个使用 minGW。
用 VS2010 WinXP 编译动态 127.488 KB
使用 MinGW gcc WinXP 1.018.639 KB 编译动态
你写了:
about 2MB when I compile using MSVC10 compiler & more that 8MB when I use GCC compile & these sizes are best cases!.
只要我们能看到任何make文件。或其他设置,这里很难提供帮助。
从以上结果可以看出,创建一个只有 128.000 KB 的 wx 应用程序是可能的。
dtx02.cpp
#include "dtx02.h"
///////////////////////////////////////////////////////////////////////////
dxDialog::dxDialog( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
wxBoxSizer* bSizer2;
bSizer2 = new wxBoxSizer( wxVERTICAL );
m_button1 = new wxButton( this, ID_SHOWMESSAGE, wxT("&Show a message"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer2->Add( m_button1, 0, wxALL, 5 );
m_button2 = new wxButton( this, wxID_OK, wxT("&Close"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer2->Add( m_button2, 0, wxALL, 5 );
m_notebook1 = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_panel1 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_panel1->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) );
m_notebook1->AddPage( m_panel1, wxT("a page"), true );
m_panel2 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_notebook1->AddPage( m_panel2, wxT("a page"), false );
bSizer2->Add( m_notebook1, 1, wxEXPAND | wxALL, 5 );
this->SetSizer( bSizer2 );
this->Layout();
this->Centre( wxBOTH );
// Connect Events
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( dxDialog::OnClosex ) );
m_button1->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( dxDialog::OnShowMessage ), NULL, this );
m_button2->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( dxDialog::OnClose ), NULL, this );
}
dxDialog::~dxDialog()
{
// Disconnect Events
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( dxDialog::OnClosex ) );
m_button1->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( dxDialog::OnShowMessage ), NULL, this );
m_button2->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( dxDialog::OnClose ), NULL, this );
}
dtx02App.cpp
#include "dtx02App.h"
#include "dtx02dxDialog.h"
IMPLEMENT_APP(dtx02App)
dtx02App::dtx02App()
{
}
dtx02App::~dtx02App()
{
}
bool dtx02App::OnInit()
{
dtx02dxDialog* dialog = new dtx02dxDialog( (wxWindow*)NULL );
dialog ->Show();
SetTopWindow( dialog );
return true;
}
dtx02dxDialog.cpp
#include "dtx02dxDialog.h"
dtx02dxDialog::dtx02dxDialog( wxWindow* parent )
:
dxDialog( parent )
{
}
void dtx02dxDialog::OnClosex( wxCloseEvent& event )
{
wxTheApp->Exit();
}
void dtx02dxDialog::OnShowMessage( wxCommandEvent& event )
{
wxMessageBox( wxT("wxFormBuilder Tut") );
}
void dtx02dxDialog::OnClose( wxCommandEvent& event )
{
wxTheApp->Exit();
}