繁体   English   中英

使用我自己构建的调试库和常规DCU在Delphi中管理非常大的代码库

[英]Managing very large codebases in Delphi using a Library of Debug and Regular DCUs I built myself

我正在尝试解决此编译错误,仅在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中)在运行时,由其关联的设计时包中的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的情况外,我们一切正常。 版本DCU位于库路径中,调试DCU位于IDE设置中的Debug DCU路径中。 面对这两个库之间的选择,Delphi的链接器似乎失败,无论何时存在两组DCU,都有这种形式的错误,当我单击Build,并且Build Configuration设置为Release时,我得到F2051错误。 F2051错误的普通原因是存在多个不兼容的二进制DCU并且都是可访问的,并且链接器无法使其全部工作。 但是,如果你想在库路径中同时使用Debug和Release DCU,我认为这种情况不会发生,因为链接器会为你选择调试或释放DCU。

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

多部分问题:

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

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

在此输入图像描述

C.如果我发生了这个问题,我应该如何防止每次构建BigApp时从源代码编译超过250万行的组件LIBRARY代码,而只是通过DCU链接它们,并且仍然有调试并释放dcus正常工作?

D.如果我转到Win32 \\ Debug文件夹并删除IdGlobal.dcu,我可以通过原始错误。 这告诉我,我的包编译(用于调试配置)正在生成INVALID IdGlobal.dcu。 这甚至可能吗? delphi可以默默输出乱码的DCU吗?

注意:我没有使用,也无法使用Runtime Packages来处理应用程序大小问题。

更新:我应该在这里做的第一件事是验证ZERO额外的DCU文件在我的硬盘驱动器上是任何地方,无论如何。 这是标准的F2051错误建议。 在我处理完这个问题后,我会更新这个问题。 似乎Delphi本身可以将DCU从一个地方复制到另一个地方,或者不在CURRENT搜索路径中的虚假DCU可能已经在某个其他项目的搜索路径中。 可能会出现一种坏DCU拷贝的桶式旅。 一旦我确定发生了什么样的坏DCU代或副本,我就会更新问题。

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

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

也许我可以对提供给编译器的搜索路径的顺序有所了解,这应该首先解释为什么问题首先发生并且可以通过在该特定位置添加Debug DCU路径来解决(至少在您的情况下) 。 所有这些观察都是用XE7进行的。

IDE中有几个位置可以指定搜索路径:

  1. 库路径 (Delphi-Options - Library)
  2. 翻译库路径 (Delphi-Options - Library-Translated)
  3. 调试DCU路径 (Delphi-Options - Library)
  4. 翻译的调试DCU路径 (Delphi-Options - Library-Translated)
  5. 搜索路径 (通过项目选项)

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

因此,为了让编译器找到我们自己的新版Indy版本的dcu文件,我们必须在1和3下的pathes前面放置相应的pathes。

现在,当Library语言被设置为与英语不同的东西时,事情会变得复杂。 在这种情况下,翻译的pathes会起作用,导致2,5,1或4,3,2,5,1的顺序,具体取决于Use debug .dcus的设置。

要使用更新的Indy版本制作上述示例,您还必须调整已翻译的广告。

罪魁祸首在于CodeGear.Delphi.Targets ,它按照这个顺序放置了pathes。 我能够修改这个文件,以便使用pathes的自然顺序:5,2,1或5,4,3,2,1。 如果有人能确认我被允许在这里显示这些变化,我会这样做。 也许我只能提供补丁。

更新:以下是Mercurial显示的XE7中CodeGear.Delphi.Targets的更改

@@ -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>

现在我理解了这个问题的来源。 请注意Rufo爵士,因为他让我想到了解决方案。

就是这样:我正在调用DCC32.exe来编译包(使用.dpk,但没有.dproj文件,并且没有调用msbuild来编译这些包)。 当我构建这些时,我没有将Debug DCU路径插入通过-I参数传递到DCC32.exe的库路径的头部。

一旦DCC32.exe程序包编译库搜索路径具有FIRST的Debug DCU文件夹,它就可以工作。

如果有人对这样的软件包系统感兴趣,我打算开源这个软件包构建系统,作为最初由Juancarlo Anez建立的WANT项目的重新启动的一部分,我可能会用一个新名称来调用它。 一旦组件构建系统的工作演示可用,我将更新此答案。

简要概述了一个工作系统,以满足我在问题中提出的要求:

  1. 您将需要一个文件(可以是xml,ini,json文件),它定义要构建的包列表。

  2. 您需要在每个上面调用MSBUILD或DCC32.exe。 你可以编写自己的代码,或者你可以使用我的代码,我会尽可能地开源代码。

  3. 只需在调用Debug项目构建时,您需要将Debug DCU DPROJ作为第一项包含在库路径中。

  4. 您将需要在项目搜索路径和库路径中使用$(OURCOMPANYLIBRARYDCU)\\$(Platform)\\$(Config)宏。

  5. 在Delphi IDE中,您需要将$(OURCOMPANYLIBRARYDCU)\\$(Platform)\\Release硬编码$(OURCOMPANYLIBRARYDCU)\\$(Platform)\\Release库路径中的路径。

  6. 在Delphi IDE中,您需要将$(OURCOMPANYLIBRARYDCU)\\$(Platform)\\Debug硬编码$(OURCOMPANYLIBRARYDCU)\\$(Platform)\\Debug Debug DCU路径中的路径。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM