我正在尝试解决此编译错误,该错误仅在Debug配置中发生,并且仅在以下情况下发生:

[dcc32 Fatal Error] MyIndyTCPChannel.pas(22): F2051 Unit IdIOHandlerSocket was compiled with a different version of IdGlobal.IdDisposeAndNil


我正在开发一个非常大的Delphi代码库,其中包含250万行内部代码和300万行组件代码,其中包括几个大型的商业Delphi组件套件(Developer Express,TeeChart等),以及大量还包括开源delphi组件,以及相当大的内部开发组件集,编号252个程序包,其中约140个是设计时+运行时或设计时,其他是运行时程序包(也已加载到IDE中)在运行时,通过其相关的designtime程序包中的DLL依赖项)。

我们的主库路径已被优化为尽可能小的路径,它包含Delphi附带的标准路径,加上我们添加的另外三个路径,主要路径是单个“ OurCompanyLibraryDCU”文件夹,该文件夹下包含用于我们使用的两个平台和两个配置:

c:\dev\OurCompanyLibraryDCU\Win32\Release
c:\dev\OurCompanyLibraryDCU\Win32\Debug
c:\dev\OurCompanyLibraryDCU\Win64\Release
c:\dev\OurCompanyLibraryDCU\Win32\Debug


上面的每个文件夹都包含用于该平台/配置组合的单个文件夹中的BPL,DCP和DCU文件集。

在项目选项中使用了如下宏,因此我们可以更改平台和配置,并正确解析目录:

$(OURCOMPANYLIBRARYDCU)\$(Platform)\$(Config)

OURCOMPANYLIBRARYDCU是环境变量,而$(X)是在Delphi IDE上下文中扩展环境变量的语法。

我正在尝试构建最重要和最大的VCL应用程序项目(称为BigApp.dproj),以便项目搜索目录仅包含我们的APPLICATION源文件夹,并且不需要项目搜索路径来包含我们所有的第三方组件LIBRARY源代码。为此,我们需要链接调试DCU或发布DCU。

到目前为止,除了您可以同时使用Debug和Release DCU的情况以外,其他所有功能都可以使用。在IDE设置中,发行版DCU在库路径中,而调试DCU在调试DCU路径中。面对这两个库之间的选择,每当两套DCU都存在时,Delphi的链接器似乎会失败,这种形式的错误,当我单击Build,并且Build Configuration设置为Release时,会出现F2051错误。 F2051错误的常见原因是存在多个不兼容的二进制DCU,并且它们都可以访问,并且链接器无法使其全部正常工作。但是,当您同时在库路径中同时需要调试和发布DCU时,我认为不会发生这种情况,因为链接程序为您选择了调试或发布DCU。

如果我还没有构建调试DCU,则不会发生上述问题。我怀疑我的Debug DCU巧妙地“无效”,或者Delphi中的Debug-DCU-selection算法不起作用,但不知道为什么,或如何解决此问题。

多部分问题:

A.每个平台/配置组合是否都有一个文件夹,在一个文件夹中包含DCU,BPL和DCP,然后添加到已知会导致问题的IDE库路径中?我需要三个子文件夹,为每个platform + config + filetype总共制作12个文件夹,还是可以通过platform + config将它们放在一起?

B.在程序包编译的情况下,是否可以让IDE库路径包含OurCompanyLibraryDCU文件夹,并且将该文件夹配置为DCP输出目录,程序包输出目录和单元输出目录?我担心的是,通过使输入文件夹和输出文件夹相同,在某些情况下编译器可能无法从.pas源重建单元,而只是链接先前编译的DCU。



C.如果我要解决这个错误,该怎么做,我应该防止每次构建BigApp时从源代码编译超过250万行的组件库代码,而是仅通过DCU进行链接,并进行调试并释放dcus正常工作?

D.如果我转到Win32 \ Debug文件夹并删除IdGlobal.dcu,则可以克服原始错误。这向我表明,我的软件包编译(用于调试配置)正在生成INVALID IdGlobal.dcu。那有可能吗? delphi可以静默输出乱码的DCU吗?

注意:我没有使用,也不能使用运行时包来处理应用程序大小的问题。

更新:我应该在这里做的第一件事是验证硬盘上的“其他”是否为零。这是标准的F2051错误建议。我会解决这个问题后再更新。 Delphi可能会自己将DCU从一个地方复制到另一个地方,或者不在当前搜索路径中的虚假DCU可能在其他项目的搜索路径中。可能会发生DCU副本损坏的情况。一旦我确定发生了哪种不良DCU生成或复制,我将更新问题。

更新2:我现在保证在构建之前不存在IdGlobal.dcu的其他副本,并且问题仍然存在。因此,问题就打开了在构建IdGlobal.dcu时使用的编译器选项,以及在Debug构建中构建BigApp.dproj时使用的编译器选项的版本。

更新3:尽管我的所有程序包编译都似乎没有错误地完成,但是在启动DCC32.exe或MSBUILD.exe生成程序包的过程中,似乎它们没有使用正确的库搜索路径。这个库路径不一致问题似乎是核心问题,这要感谢Rufo爵士指出。

最佳答案

也许我可以弄清楚呈现给编译器的搜索路径的顺序,这应该清楚说明为什么问题首先出现并且可以通过在该特定位置添加Debug DCU路径来解决(至少在您的情况下) 。所有这些观察都是使用XE7进行的。

IDE中有几个地方可以指定搜索路径:


库路径(Delphi-Options-库)
翻译的库路径(Delphi-Options-库翻译)
调试DCU路径(Delphi-Options-库)
转换后的调试DCU路径(Delphi-Options-库已转换)
搜索路径(通过项目选项)


当库语言设置为英语时,这些路径将以5,1或3,5,1的顺序提供给编译器,具体取决于Use debug .dcus的设置。这已经有点怪异了,因为debug dcu路径优先于项目搜索路径。

所以为了使编译器能够找到我们自己的较新Indy版本的dcu文件,我们必须将相应的路径放在1和3下的路径之前。

现在,当库语言设置为不同于英语的语言时,事情变得复杂。在这种情况下,取决于Use debug .dcus的设置,转换后的路径会起作用,导致顺序为2,5,1或4,3,2,5,1。

为了使上面的示例具有较新的Indy版本,您还必须调整翻译后的路径。

罪魁祸首位于CodeGear.Delphi.Targets中,该路径按此顺序放置路径。我能够修改此文件,以便使用路径的自然顺序:5,2,1或5,4,3,2,1。如果有人可以确认允许我在此处显示这些更改,我将这样做。也许我只能提供一个补丁。

更新:这是XE7对CodeGear.Delphi.Targets的更改,如Mercurial所示

@@ -122,20 +122,19 @@
     <DcpFilename Condition="'$(DcpFilename)'!='' And !HasTrailingSlash('$(DcpFilename)')">$(DcpFilename)\</DcpFilename>
     <DcpFilename Condition="'$(DcpFilename)'!=''">$(DcpFilename)$(MSBuildProjectName).dcp</DcpFilename>

-    <UnitSearchPath Condition="'$(DCC_UnitSearchPath)' != ''">$(DCC_UnitSearchPath);$(DelphiLibraryPath)</UnitSearchPath>
-    <UnitSearchPath Condition="'$(DCC_UnitSearchPath)' == ''">$(DelphiLibraryPath)</UnitSearchPath>
-
+    <UnitSearchPath>$(DelphiLibraryPath)</UnitSearchPath>
     <UnitSearchPath Condition="'$(DCC_TranslatedLibraryPath)' != ''">$(DCC_TranslatedLibraryPath);$(UnitSearchPath)</UnitSearchPath>
     <UnitSearchPath Condition="'$(DCC_DebugDCUs)'=='true' And '$(DelphiDebugDCUPath)'!=''">$(DelphiDebugDCUPath);$(UnitSearchPath)</UnitSearchPath>
     <UnitSearchPath Condition="'$(DCC_DebugDCUs)'=='true' And '$(DCC_TranslatedDebugLibraryPath)' != ''">$(DCC_TranslatedDebugLibraryPath);$(UnitSearchPath)</UnitSearchPath>
-
+    <UnitSearchPath Condition="'$(DCC_UnitSearchPath)' != ''">$(DCC_UnitSearchPath);$(UnitSearchPath)</UnitSearchPath>
+
     <___ResourcePath Condition="'$(DCC_ResourcePath)' != ''">$(DCC_ResourcePath);$(DelphiLibraryPath)</___ResourcePath>
     <___ResourcePath Condition="'$(DCC_ResourcePath)' == ''">$(DelphiLibraryPath)</___ResourcePath>
+    <___ResourcePath Condition="'$(DCC_TranslatedResourcePath)' != ''">$(DCC_TranslatedResourcePath);$(___ResourcePath)</___ResourcePath>
     <__ResourcePath Condition="'$(DCC_UnitSearchPath)' != ''">$(DCC_UnitSearchPath);$(___ResourcePath)</__ResourcePath>
     <__ResourcePath Condition="'$(DCC_UnitSearchPath)' == ''">$(___ResourcePath)</__ResourcePath>
     <ResourcePath Condition="'$(BRCC_OutputDir)' != ''">$(BRCC_OutputDir);$(__ResourcePath)</ResourcePath>
     <ResourcePath Condition="'$(BRCC_OutputDir)' == ''">$(__ResourcePath)</ResourcePath>
-    <ResourcePath Condition="'$(DCC_TranslatedResourcePath)' != ''">$(DCC_TranslatedResourcePath);$(ResourcePath)</ResourcePath>

     <NameSpace Condition="'DelphiNamespaceSearchPath'!=''">$(NameSpace);$(DelphiNamespaceSearchPath)</NameSpace>

关于delphi - 我使用自己构建的调试库和常规DCU在Delphi中管理超大型代码库,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28631267/

10-10 16:56