【问题标题】:Delphi package problem : Packaged units must refer only to packaged units.. (E2411)Delphi 封装问题:封装单元必须仅指封装单元.. (E2411)
【发布时间】:2011-11-13 06:36:01
【问题描述】:

我得到的错误是这样的:

[DCC Fatal Error] myunit3.pas(244): E2411 Unit XBAT in package B_Dsgn refers to unit QBEE which is not found in any package. Packaged units must refer only to packaged units

我需要知道我遇到的这个错误的真正含义,以及如果可能的话如何排除和解决这些问题,特别是当错误消息中陈述的事实不正确时(这些单位实际上是指其他单位)其他有效的软件包)。

此类问题涉及包依赖关系。我在一系列三个设计时和三个运行时包方面遇到了一个有趣的问题,如下所示:

最奇怪的是,每次我清理和重建时,我都会在错误中得到一个不同的单元名称。 (上面显示的 Unit XBAT 指的是单元 QBEE)。

另一个奇怪的地方是它指的是处于顶级依赖关系中的单元,并且是已经构建的包的一部分。

步骤;

  1. 编译A,就可以了。
  2. 编译A_Dsgn,就可以了。
  3. 编译 B,就可以了。
  4. 编译B_Dsgn,就可以了。
  5. 编译 C,它失败并出现此 E2411 错误。

由于我怀疑有人能告诉我如何准确地解决这个问题,我正在寻找解决包中复杂依赖问题的步骤。例如,上述错误的字面意思表明,我应该有一个关于隐式链接单元的相应消息,而我没有。我已将所有隐式使用的单位添加到基本包 A 和 B,因此不会发出隐式单位警告。

我的下一个想法是将每个包的 DCU 输出文件夹分开,以防止 DCU 输出混淆编译器。现在我什至无法构建包。

更新我尝试使用 Explicit RebuildRebuild as Needed 选项。我发现此错误与打开“按需重建”有关。当它关闭时,软件包会失败,并出现其他更重要的错误。我觉得奇怪的是编译器会发出奇怪的错误,可以通过关闭Rebuild as needed 来禁用这些错误。有什么想法吗?

更新 2 基本的底层问题并不能通过打开或关闭显式重建来解决。我没有收到此错误,而是遇到烦人的运行时/设计时包问题,这导致一组包无法同时加载。 (无法加载包 foo,因为它包含单元 bar,它也在包 bat 中。您想在下次加载项目时尝试加载此包吗?)。

【问题讨论】:

  • 如果我理解正确,当检查“根据需要重建”时,然后建立c触发b的重建,后者触发了b_dsgn的重建 - 你确定你确定你是否有人t 引入了某种从 C/C_Dsgn 到 B/B_Dsgn 的循环依赖?
  • 你在使用weak packaging吗?
  • 好问题。明天上班我会搜索弱包装的参考。
  • @TOndrej:我看不出 pacakging 与它有什么关系。这不会改变哪个单元包含在哪个包中以及引用了哪些单元。它仅更改单元的链接方式(始终作为 BPL 的一部分或仅在需要时从 .dcp 文件复制并直接链接)。
  • IMO,这是一个delphi编译器错误。

标签: delphi compiler-errors delphi-xe


【解决方案1】:

我怀疑这是一个不起眼的编译器错误。

我体验过的项目至少有4级依赖运行时包:

PackageA

E2411 包 PackageD 中的单元 '%s' 引用了单元 '%s' 而不是 在任何包装中都可以找到。包装单位必须仅指包装单位。

我发现唯一可行的解​​决方案是制作包 A、B 和 C 从不构建(即显式构建)包,并改用 Project Dependencies 强制构建顺序。我必须让这三个永远不会构建,否则我会得到

E2220 从不构建包“%s”需要始终构建包“%s”

我知道它可能不是您要找的答案,但它确实存在。

顺便说一句,这发生在我的 Delphi 2009 中。

【讨论】:

  • 这与我的经验一致。我希望我可以生成一个可移植的可重现此错误的实例,以便我可以在 QC 中报告它。
  • 我觉得 docwiki 在这里很有帮助:never build 表示接口已修复,而 always build 表示仍在开发中:docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/…
  • 这就是文档所说的。我认为它的真正含义是“Delphi 中的依赖管理系统被巧妙地破坏并需要修复,但在我们修复它之前,您可以在完成项目开发时将其关闭,并且当我们的依赖系统以固定方式失败”。
  • 谢谢肯尼斯。我在 Delphi XE2 中遇到了示例问题,您的建议奏效了。
  • 该死的。这个解决方案对我不起作用,因为包 A 包含经常使用/更新/改进的实用程序。包 A 必须始终编译!每个人都依赖包 A。
【解决方案2】:

这很简单:如果 C 中的一个单元引用了一个不在包 C 引用的任何包中的单元,则该单元应该包含在 C 中,或者可以在其中找到它的包应该由 C 引用。如有必要,将设备放入自己的包装中。

您放置哪个单元取决于依赖项。像你一样把它画出来是有意义的,但要使用单位级别的分辨率。

更新

您的更新 1 和更新 2 仍然让我认为您的单位之一使用的单位(直接或间接)未正确引用。甚至可能是 RTL 或 VCL 单元。由于您有设计包,我假设您在其中有组件。

IME,要包含的最小包集是

requires
  rtl,
  designide,
  vcl,
  vclactnband,
  vclx,
  xmlrtl;

【讨论】:

  • 我是说我理解这是此错误消息的字面意思,但是,在这种情况下,所有此类单元都已正式(明确)包含在每个包中,并且没有此类隐含或缺失单位。
  • 但是是否所有引用的包都必须引用?如果没有,可以直接链接一个单元。
  • 我相信是这样,但要验证这一点非常非常困难。除了您列出的通常的 VCl 嫌疑人之外,在这个“代码生态系统”中还有 100 多个其他包,其中任何一个都可能包含一个单元,从而产生缺失的依赖关系。由于所讨论的单元已经过仔细验证,因此除了错误消息中的依赖项之外,缺少的依赖项似乎表明存在某种编译器错误。
  • 在这种情况下,我几乎不相信编译器错误。如果我看到类似的情况发生,则 IME 是我的设置中的一个错误。
  • 两者都可以同时进行。由于缺少正确的编译器错误消息,我的设置中的错误几乎无法发现。正常的“隐式导入”警告没有发生,同时出现了其他问题,并且出现了错误的错误消息。再多摆弄其他选项也无法从设置中获得正确的包消息。
【解决方案3】:

在给出错误的项目中必须按要求添加。 dcp 错误。

在你的情况下:

[DCC 致命错误] myunit3.pas (244): E2411 Unit in package B_Dsgn XBAT 指的是未在任何包中找到的单元 QBEE。必须仅将打包单元引用到打包单元

在myunit3.pas驱动的包中,添加必需的:QBEE

至少我做到了。

【讨论】:

    【解决方案4】:

    您正在使用 XBAT 单元中的 QBEE 单元,在这种情况下,您有四个选项:

    1- 您没有将 QBEE 添加到包 B_Dsgncontains 列表中。

    2- 如果 QBEE 已经包含在另一个包中,我们将其称为 Original_Package 那么您应该将该包添加到 requires 列表中strong>B_Dsgn 且不包含单位。

    3- Original_Package

    {$IMPLICITBUILD ON}

    在它的 dpk 文件中,所以首先您需要关闭 IMPLICITBUILD 并构建 Original_Package,然后您可以构建您的 B_Dsgn 包。

    4-您可能在 B_Dsgn 中没有 XBAT,但您在另一个中间包中拥有它,我们将其称为 B_Run 并且您有B_RunB_Dsgn 的需求列表中,在这种情况下,首先尝试使用上面三个选项之一修复 B_Run,然后构建它,之后您可以构建 B_Dsgn

    注意:

    • 最后两个案例可以复制一长串单位,而不仅仅是两个或三个相互需要的包,在这种情况下,所有包都应该关闭IMPLICITBUILD
    • 在构建之前清理影响问题的每个包的代码。

    祝你好运

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-23
      相关资源
      最近更新 更多