簡體   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