为什么编译器会将不属于当前包的DCU放在它的单元输出目录中?

Why does the compiler place DCUs that do not belong to the current package in its unit output directory?

我创建了两个包,P1.dprojP2.dproj

我将两个空单元放入包中,因此 P1 包含 Unit1.pasP2 包含 Unit2.pas

我在各自的包中将单元输出目录编辑为 .\P1$(Platform)$(Config).\P2$(Platform)$(Config)

我添加了P1作为对P2项目的引用,所以P2依赖于P1。

项目文件存储在同一文件夹中。

目录结构如下所示:

  Root\
    Source\
      P1\
        Unit1.pas
      P2\
        Unit2.pas
    Packages\
      P1.dpk
      P1.dproj
      P2.dpk
      P2.dproj
      P1\
        Win32\
          Debug\
      P2\
        Win32\
          Debug\

在我添加依赖项之前,P1 输出 Packages\P1\Win32\Debug\Unit1.dcu,P2 输出 Packages\P21\Win32\Debug\Unit2.dcu

没有意外。

在我刚刚构建 P2 时添加依赖项后,IDE 也会自动编译 P1,但是 Unit1.dcu 文件现在输出到 Packages\P2\Win32\Debug\Unit1.dcu.

这是为什么?

Unit1.dcu 文件不在 P2.drojContains 列表中,也不在任何库路径或浏览路径中列出(Delphi 全局或项目本地).

为什么编译器会把它甚至无法访问源目录的内容放到当前项目的单元输出目录中?

当我将 P1 dpk/dproj 文件移到某个子文件夹并重新启动 IDE 时,它会正确地抱怨找不到 P1.dcp 文件并且不会开始编译来自 P1 的任何内容。

我在一个更大、更复杂的设置中注意到了这种行为,这让我发疯 ...

这样做是因为两个包的源文件都在同一目录中 P1 在其项目选项中设置为"Rebuild as needed"。

考虑一个包含并使用单元 U1 的简单项目 Proj1。 U1 使用 not 包含在 Proj1 中的 U2。编译器必须能够看到 U2.dcu;可能在当前库路径或其他一些常见的 "lib" 目录中。编译 Proj1 时,U1.dcu 进入 Proj1 的单元输出目录,但 U2.dcu 只是来自当前所在位置的 "used",不会出现在 Proj1 的单元输出目录中。

现在,假设您将 U2.pas 所在的目录添加到 Proj1 的搜索路径中。现在编译器可以看到 U2.pas,因此编译它并将生成的 U2.dcu 与 U1.dcu

一起放入 Proj1 的单元输出目录

这里也是一样的...P2 "requires" P1。也就是说,在编译 P2 时,编译器需要查看 P1 的 P1.DCP 或所有源文件(在本例中为 P1.dpk 和 unit1.pas)。

在你的情况下,它可以看到 P1.dpk 因为它在同一目录中,所以它编译它并将生成的 dcu(在本例中为 unit1.dcu)放入 P2 的单元输出目录。

您可以通过在其项目选项中将 P1 设置为 "Explicit Rebuild" 来防止此行为。在构建 P2 或 "requires" P1 的任何包时,这会告诉编译器 "even though you can see P1's source, do not build it."