Delphi中编译和构建有什么区别?

24

使用Delphi-6有两个选项:构建和编译。

我知道运行程序时只会编译已更改的文件并对未更改的文件使用DCU。 当我点击“构建”时,它会重新构建DCU。

我一直在想,当我制作一个发布的程序(更改构建设置、条件变量等)时,我是否只需要编译,还是必须进行完整的构建?

如果我不进行完整的构建,会有什么后果吗?

4个回答

29

@Daisetsu,以下是“构建”和“编译”的区别:

构建会在源代码可用时编译项目中的所有被使用单元。

编译仅编译已更改的被使用单元。

根据我的个人经验,当您更改编译器配置时,必须执行应用程序的构建操作,以便更改将反映在项目的所有单元中。


好吧,除了标记为 $implicitbuild off 的包(单元?)之外。 - Marco van de Voort

21

何时进行构建(build),何时进行编译(compile)?

当且仅当 .pas 源文件的时间戳发生变化 (1,2) 时,编译器才会自动重新编译单元。

对于项目中的其他状态更改(如指令、调试或其他编译器设置等),编译器不会自动重新编译。这时您需要强制执行一次构建。

还需要在 .inc 或其他包含的($I)文件发生更改时进行强制重建(3),因为它们的时间戳不会被检查。

因此简而言之,当除了单元.pas 文件以外的任何内容发生更改时,您需要进行构建。

在构建过程中,有一些奇怪的情况。大多数情况下会出现“找不到单位xxx”的错误,尽管它看起来已经存在。

  1. 一个是当项目中的单元路径错误或使用相对路径时,而工作目录又不正确时。(请参考Delphi debug a wrong unit)
  2. (我对这个不是完全确定,这只是一个假设) 由于 CRCs(1),.dcu 已重新编译,但新编译的 dcu 放置在不同的目录中。对于当前的编译来说,这不是一个问题 (因为正确的 dcu 已经被加载了),但在后续的编译(例如依赖包) 中,旧的 dcu 文件会再次被找到,而源文件则不会 -> 出现错误。如果有疑问,请始终通过递归删除所有DCU来清理您的构建目录
  3. .dpr 中提到的单元路径是错误的

(1) 如果 Delphi 就像 FPC 一样,.dcu 包含它所依赖的所有dcu接口部分的 CRC。这可以用于检查是否需要进行额外的重新编译。例如由于对文件系统的操作(移动dcu)

(2) 对于专家而言,也可以看看 {$implicitbuild xx}

(3) 与 Delphi 不同,FPC 在更改 .inc 文件时会重新编译。FPC 项目内部大量使用 .inc 文件,这个改变早在支持 Delphi 之前就已经存在了。 因此,将“defines”inc 文件复制到任何目录中的包无法与 FPC 编译,因为它们通常具有略微不同的大小和 CRC。Indy(10)是一个很好的例子。


1
Gexperts 包含一个文件清理器,以便于清理旧的 DCU 文件。 - Fabricio Araujo

3

当更改设置时,您应该始终进行构建。

以前编译的DCU文件可能使用不同的设置进行编译,例如编译器定义。这可能会导致同一项目中的两个单元使用不同的设置进行编译。


这也是我的个人经验。但是,既然每个人都知道在更改设置时必须重新构建项目,为什么不让IDE为我完成呢? - Heinz Z.
请看下面,我将其设为维基页面,以便人们可以在了解更多信息后进行完善。 - Marco van de Voort

3
准备发布时,您应该绝对进行完整的构建。没有任何借口可以不这样做,Delphi编译器足够快。
澄清可重现版本的重要性:
  • 准备发布时,您将拥有其他人将使用的产品版本。
  • 如果他们报告问题,您可能需要返回到该版本以测试和修复问题。
  • 如果您没有进行完整的构建,而是依赖于现有的DCU,则存在一个机会,即您的某个源文件未重新编译。
  • 即使这种可能性相当小,这种机会也会严重影响您快速解决问题的能力。
  • 随着系统变得更大、具有更多的相互依赖关系并在“野外支持”的更多版本中,此问题变得更加严重。
为了保持自己的理智,我强烈建议您始终为可发布版本进行完整的构建。
即使是非发布版本,我也经常进行完整构建。

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