C++ Builder XE4相较于C++ Builder 2010,为何EXE文件大小会增加三倍?

9
我已将一个项目从RAD Studio 2010升级到RAD Studio XE4。该项目主要使用RAD Studio的C++ Builder部分,其中夹杂着一些Delphi代码。
在2010下,Release版本为22MB。在XE4下,相同的Release版本为55MB。
这是一个问题,因为:
- 55MB对于一个EXE来说非常大。 - 启动程序需要更长的时间(不多,但有一些)。 - 许多客户从偏远地区或在海上时下载新版本。大小很重要。
是什么导致了这个问题,如何解决?

笔记

  • 奇怪的是,调试版本仍然只有23MB。项目设置看起来非常相似。我对选项集的导出进行了比较,只看到<UsePackages>True</UsePackages>作为Release中存在而Debug中不存在的内容;删除它没有任何影响。除此之外,还开启了代码优化并缺少_DEBUG定义。
  • 对于发布版本生成了调试信息,但是放入了一个外部的.tds文件。(这将在未来用于EurekaLog,并且目前允许我们调试程序的发布版本。)我想知道链接器是否正在链接调试信息,但据我所知,C++链接器总是将调试信息放在一个外部文件中,该文件已经存在,此外EurekaLog尚未在构建中启用。
  • 项目文件(.cbproj)是在XE4中创建的,而不是从旧的2010文件升级而来。我创建了新的项目并添加了旧的.cpp和.pas文件。这是为了避免由升级引起的问题 - 在Embarcadero论坛上,经常建议在升级IDE版本时重新创建项目。在此之前,我确实遇到的问题比2010年少。
  • 有很多提到Delphi XE2+ EXE比旧版Delphi生成的EXE要大得多的地方。(1, 2, 3, 4, 5, 6)。虽然C++链接器与Delphi使用的不同,但是可能导致相似的原因。
    那里的原因似乎主要是由Delphi RTL代码使用的RTTI引起的,在Delphi项目中可以通过指定{$WEAKLINKRTTI ON}来删除它。XE4文档没有提到等效的C++链接器编译器指示符。有#pragma explicit_rtti{$RTTI}的C++类比)和__declspec(delphirtti){$M}/{$TYPEINFO}的C++类比)。
  • 该项目使用运行时包和动态RTL进行链接。这是一个32位VCL窗体应用程序。我在Windows 7上安装了XE4更新1。
  • 编辑:David Heffernan在下面的评论中询问每个项目的.map文件大小。
    发布版.map大小为17MB,.tds大小为80MB。
    调试现在已经停止链接,链接器报告内存不足(一个旧的,旧的错误,应该在几年前就修复了)。没有生成.map或.tds文件,因此我无法准确地给出比较大小。从记忆中,.tds大约为100MB,不幸的是我不记得.map大小。如果我让项目链接,我会更新问题。
  • 再次编辑:我找到了答案(有点),将“展开内联函数”关闭可以将EXE大小减小到预期值。但这本身就很令人困惑——请参见下面我的答案。请注意,调试版本已经关闭了此选项,仍然无法链接,并显示内存不足错误。
    我还没有将我的答案标记为正确,因为有人可能能够提供关于正在发生的事情的确切见解,这将是比“关闭此选项”更好的答案。

你比较过这两个项目的地图吗?55 MB是非常惊人的,考虑到所有Emba代码都在一个包中。 - David Heffernan
现在我已经成功地停止了两个项目的链接,所以很抱歉暂时无法立即回答。周一我会回复你的。从记忆中,它们都生成了大约100MB的.tds文件,关于.map文件的存在和大小我不太清楚。当不是周五下午17:00之后的疲惫长周时,我将尽力给出更好的答案。:p - David
@DavidHeffernan 我更新了问题来回答你。我昨天花了一整天的时间尝试让Debug链接 - 链接器突然报告内存不足。根据 SVN 的记录,没有任何更改。但是,我报告了Release构建的文件大小,并添加了有关项目创建方式的注释。 - David
我没有让你比较地图文件的大小。我让你比较地图文件。地图文件告诉你文件中有什么。 - David Heffernan
抱歉,我误解了你的回复。目前为止,我仍然无法使调试版本链接,因此没有调试.map文件可以比较。 - David
1个回答

8
解决了(有点)。
Release 版本的“扩展内联函数”被打开了。关闭此选项将 EXE 文件大小从 55MB 减小到了 17MB。 项目选项中 C++ 编译器 - 调试部分显示“扩展内联函数”选项的截图 这是一个令人惊讶的差异,我不知道为什么差别这么大。即使计算模板和头文件,更不用说使用 inline 关键字的函数,我们也不太可能有价值 38MB 的内联函数。如果有一种方法可以检查链接器步骤、输出或 obj 文件以查看正在扩展的内容,请评论 - 我会觉得非常有价值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接