在新的VCL应用程序中,编译和构建操作会产生相同的二进制文件和映射文件(即使“包含版本信息”,也会在.exe文件的末尾略有不同在项目“选项被关闭 - 已经讨论过”。映射文件的字节与字节相同。但是,我添加任何第三方组件,Build和Compile生成的二进制和map(!)文件明显不同!
测试了两个版本的Delphi:
- 7.0版(Build 8.1)
- CodeGear™RAD Studio 2007版本11。0。1902。0471(+ 2007年12月更新)
重现步骤:
我们有几乎不同的.exe文件和完全相同的.map文件。然后,如果我们再次重复所有步骤但在项目第三方组件中使用(我尝试ODAC,DOA,DevExpress和selfmade),我们会得到更多不同的.exe和不同的.map文件。
为什么呢?有什么建议吗?
更新
关于我如何找到这个以及为什么它让我感兴趣的一些信息:
Project是使用MSBuild从简单的脚本构建的。当在项目中添加了通过ITE(带有资源的dll)的翻译时,我发现当项目是Build(来自脚本或来自IDE)时 - 翻译版本工作错误 - 按钮,标签等上的某些文本来自错误的地方(字面意思来自另一个按钮,标签)。当项目从IDE编译时 - 一切正常。所以我开始比较Build和Compile输出......
答案 0 :(得分:10)
您所看到的只是编译器内置make逻辑的工件。当您进行构建时,它会告诉编译器构建所有可用的源。因此,Delphi处理每个源文件以及它找到源的使用列表中的每个单元,然后它将构建该文件。它以递归方式执行此操作。编译时,只加载现有的.dcu文件,如果发现它们是最新的,则不执行任何操作。这实际上可以导致发现单元的不同顺序,因为每个.dcu将有效地“展平”使用列表。由于单元是以不同的顺序被发现和加载的,因此它们是相反的,以不同的顺序链接。这就是您的地图文件看起来如此不同的原因。给定相同的源,如果您连续执行两个构建或连续两个编译,则映射文件应该相同。
差异的其他原因更为平凡,包括PE标题时间戳以及其他填充和对齐位。
答案 1 :(得分:3)
我相信这个答案有两个部分。
您看到的部分问题IIRC是编译器在执行编译/构建之前不会将内存清零。因此,未初始化的存储器中的任何内容都会成为输出中的填充符,以便进行对齐。
我似乎还记得应用程序的pe头信息中包含日期时间戳。每次都会造成不同。
我不是确认这一点的最佳人选,但这是我从过去的讨论中回忆起来的。
像Allen Bauer或Barry Kelly这样的人可能会提供更好/更准确的信息。
答案 2 :(得分:0)
如果在项目中使用编译器定义并且只是更改了它们,那么如果进行编译,则不会看到对dcu和生成的模块(exe或dll)的任何更改。如果进行完全重建,则在新创建的dcu和模块中使用编译器定义。
我在一个大型项目组中看到过这种情况,我们在不同项目中使用具有不同定义的模块,并且所有dcu都存储在同一目录中。
Ergo:在这种情况下,编译器不会对定义强制执行依赖项。
也许你确实看到了同样的问题。