【发布时间】:2013-09-17 17:42:46
【问题描述】:
我已将项目从 RAD Studio 2010 升级到 RAD Studio XE4。该项目主要是 C++,使用 RAD Studio 的 C++ Builder 部分,以及少量的 Delphi。
在 2010 年,发布版本为 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 documentation does not mention an equivalent C++ linker pragma。有#pragma explicit_rtti({$RTTI}的 C++ 模拟)和__declspec(delphirtti)({$M}/{$TYPEINFO}的 C++ 模拟)。 - 使用运行时包和动态 RTL 链接项目。它是一个 32 位的 VCL 表单应用程序。我在 Windows 7 上安装了 XE4 Update 1。
-
编辑:David Heffernan 在下面的评论中询问每个项目的 .map 文件大小。
release .map 大小为 17MB,.tds 大小为 80MB。
Debug 现在已经停止链接,链接器报告它内存不足(一个旧的、旧的错误,应该在几年前修复。)没有生成 .map 或 .tds 文件,所以我不能给出比较大小准确。从内存中 .tds 大约是 100MB,不幸的是我不记得 .map 的大小了。如果我得到项目链接,我会更新问题。 -
再次编辑:我找到了答案 (sortof) - 关闭“扩展内联函数”会将 EXE 大小减小到预期值。不过,这本身就令人费解-请参阅下面的答案。请注意,调试版本已关闭此功能,但仍无法链接,从而出现内存不足错误。
我还没有将我的答案标记为正确,以防有人可以提供一些关于到底发生了什么的见解,这将是一个比“关闭此选项”更好的答案。
【问题讨论】:
-
你对比过这两个项目的地图吗?考虑到所有 Emba 代码都在一个包中,55 MB 是非同寻常的。
-
现在我已经设法完全停止两个项目的链接,所以我无法立即回答,抱歉。我会在星期一。从内存中,它们都生成了 100MB 左右的 .tds 文件,我不记得 .map 文件的存在和大小。经过漫长的一周后,我会努力在周五下午 17:00 之前给出更好的答案:p
-
@DavidHeffernan 我更新了这个问题来回答你。我昨天花了所有时间试图让 Debug 链接 - 链接器报告内存不足,不知从何而来。根据 SVN,什么都没有改变。但是,我报告了发布版本的文件大小,并添加了有关如何创建项目的注释。
-
我没有让你比较地图文件的大小。我让你比较地图文件。地图文件告诉您文件中的内容。
-
对不起,我误解了你的回复。尽管如此,我仍然无法获得要链接的调试版本,因此目前还没有要比较的调试 .map 文件。
标签: delphi linker c++builder c++builder-xe4