在新的VCL应用程序中 编译建造 操作产生相同的二进制文件和映射文件(即使“在项目中包含版本信息”选项已关闭 - 已经讨论过的“包含版本信息”选项,在.exe文件的末尾存在较小的差异)。地图文件是相同的字节到字节。但是WEN我添加了由构建和编译产生的二进制和地图(!)文件的任何第三方组件都显着不同!

在两个版本的Delphi上进行了测试:
- 版本7.0(构建8.1)
-Codegear™Rad Studio 2007版本11.0.2902.10471(+2007年12月更新)

繁殖的步骤:

  1. 创建新的VCL应用程序。可能会添加任何本机Delphi组件(我尝试从Standart,额外,Win32和System Tab中的所有组件)。
  2. 在项目选项的链接选项卡上打开详细的地图文件。
  3. 构建项目.
  4. 重命名输出.exe和.map文件(例如:project1.exe to project1b.exe和project1.map to project1b.map)。
  5. 编译项目.
  6. 重命名输出.exe和.map文件(例如:project1.exe to project1c.exe和project1.map to project1c.map)。
  7. 比较步骤4和6的文件(我使用Winmerge 2.12.4.0)。

我们几乎没有不同的.exe文件和完全相同的.map文件。然后,如果我们再次重复所有步骤,但是使用项目第三方组件(我尝试ODAC,DOA,DEVEXPRESS和自我制作),我们会获得更多不同的.exe和不同的.map文件。

为什么?有什么建议么?

更新
有关我如何找到这个以及为什么我感兴趣的一些信息:
项目是从使用MSBuild的简单脚本构建的。在项目中添加翻译(带有资源的DLL)时,我发现当项目构建(来自脚本或IDE)时 - 翻译版本的工作错误 - 某些文字在按钮,标签等。按钮,标签)。当项目从IDE编译时 - 一切都可以。因此,我开始比较构建和编译输出...

有帮助吗?

解决方案

您看到的只是编译器内置的制造逻辑的工件。当您进行构建时,它告诉编译器构建所有可用来源。因此,delphi处理每个源文件和使用源的使用列表中的每个单元,然后将构建该文件。它递归地做到这一点。当您进行编译时,仅加载了现有的.dcu文件,并且发现它们是最新的,则无需完成。这实际上可以导致发现单位的不同顺序,因为每个.dcu都会有效地“变平”使用列表。由于单位是以不同的顺序发现和加载的,因此它们是在弯曲的,以不同的顺序链接。这就是为什么您的地图文件看起来如此不同的原因。给定相同的来源,如果您在一排或两个编译中进行两个构建,则映射文件应相同。

差异的其他原因是更平凡的,包括PE标头时间戳记以及其他填充和对齐。

其他提示

我相信这个答案有两个部分。

您看到的部分问题是,IIRC是编译器在进行编译/构建之前并不为零。因此,出于对齐目的,在非初始化的内存中剩下的任何东西都变成了输出中的填充物。

我似乎还记得,PE标题信息中包含一个日期时间戳,用于应用程序。每次都会引起差异。

我不是确认这一点的最佳人选,但这似乎是我过去的讨论中回想起的。

像艾伦·鲍尔(Allen Bauer)或巴里·凯利(Barry Kelly)这样的人可能会为此提供更好/更准确的信息。

如果您使用编译器在项目中定义并将其更改,则如果进行编译,则将看到DCU和生成的模块(EXE或DLL)的任何更改。如果您进行了完整的重建,则编译器定义将在新创建的DCU和模块中使用。

我已经在一个大型项目组中看到了这一点,在一个大型项目组中,我们在具有不同定义的不同项目中使用模块,并且所有DCU都存储在同一目录中。

ERGO:编译器在这种情况下没有强制执行对定义的依赖关系。

也许您确实看到了同样的问题。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top