2015-02-20 8 views
9

che sto cercando di risolvere questo errore di compilazione, si verificano solo in Debug config, e solo nel caso descritto di seguito:Gestione molto grandi basi di codice in Delphi utilizzando una libreria di debug e regolare DCU mi sono costruito

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

Sto lavorando su una base di codice Delphi di grandi dimensioni, con 2,5 milioni di linee di codice interno e 3 milioni di righe di codice componente, che include diverse grandi suite di componenti Delphi commerciali (Developer Express, TeeChart e altri) e un numero elevato anche dei componenti open source delphi, oltre a un set di componenti sviluppato internamente piuttosto grande, con una numerazione di 252 pacchetti, di cui circa 140 designtime + runtime o designtime, mentre gli altri sono pacchetti di runtime (anch'essi caricati, i nto l'IDE in fase di esecuzione, da dipendenze DLL nel pacchetto designtime associato).

Il nostro percorso di libreria principale è stato ottimizzato per essere piccolo come può essere e contiene i percorsi forniti da Delphi come standard, più altri tre che abbiamo aggiunto, quello primario è una singola cartella "OurCompanyLibraryDCU", che contiene sotto di essa cartelle per le due piattaforme e di due configurazioni che usiamo:

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

Ognuna delle cartelle di cui sopra contiene l'insieme di file DCU BPL, DCP, e in una singola cartella, per la combinazione della piattaforma/config.

Una macro come il seguente, nelle opzioni di progetto viene utilizzato, in modo che possiamo cambiare piattaforma e configurazione, e hanno le directory risolvono correttamente:

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

OURCOMPANYLIBRARYDCU è una variabile di ambiente e $(X) è la sintassi per espandere una variabile d'ambiente, nel contesto dell'IDE di Delphi.

Sto cercando di ottenere il progetto di applicazione VCL più importante e più grande (chiamarlo BigApp.dproj) in modo che la directory di ricerca del progetto contenga solo le cartelle di origine APPLICAZIONE e non abbia bisogno del percorso di ricerca del progetto per contenere tutto il nostro codice sorgente LIBRARY di componenti di terze parti. Per fare ciò, dobbiamo collegarci alle DCU di debug o rilasciare DCU.

Finora abbiamo tutto a posto salvo il caso in cui sono disponibili sia le debug che le nuove DCU. Le DCU di rilascio si trovano nel percorso della libreria e le DCU di debug si trovano nel percorso Debug DCU, nelle impostazioni IDE. Confrontato con la scelta tra queste due librerie, il linker di Delphi sembra fallire, quando esistono entrambi i set di DCU, con errori in questo formato, quando faccio clic su Build, e Build Configuration è impostato su Release, ottengo errori F2051. La causa normale di un errore F2051 è che esistono più DCU binari incompatibili e sono entrambi accessibili e il linker non riesce a far funzionare tutto. Tuttavia, quando si desidera eseguire il debug e il rilascio di DCU sia nel percorso della libreria, ho pensato che questo genere di cose non si verificherebbe, a causa del linker che seleziona per te il debug o il rilascio delle DCU.

Se non si creano le DCU di debug, il problema precedente non si verifica. Sospetto che le mie DCU di debug siano leggermente "non valide" o che l'algoritmo di selezione di Debug-DCU all'interno di Delphi non funzioni, ma non abbiamo idea del perché o di come risolvere questo problema.

Multi-parte-Domanda:

A. sta avendo una singola cartella per ogni combinazione della piattaforma/config, che contiene la DCU, BPL, e DCP in una singola cartella, e quindi aggiunto al percorso IDE Biblioteca noto causare problemi? Ho bisogno di tre sottocartelle, per un totale di 12 cartelle per ogni piattaforma + config + filetype, oppure posso tenerle insieme per piattaforma + configurazione?

B. In una situazione di compilazione del pacchetto, è possibile che il percorso della libreria IDE contenga la cartella OurCompanyLibraryDCU e che tale cartella sia configurata come Directory di output DCP, Directory di output del pacchetto e Directory di output unità? La mia preoccupazione è che avendo la cartella di input e le cartelle di output uguali, c'è un caso in cui il compilatore potrebbe non riuscire a ricostruire un'unità dal sorgente .pas e semplicemente collegando la DCU del precedente compilatore.

enter image description here

C. Se ho intenzione di questo male, come invece, sono io evitare che gli oltre 2,5 milioni di linee di codice libreria di componenti di essere compilato dai sorgenti ogni volta che costruire la mia BigApp, invece unico collegamento loro tramite DCU e hanno ancora il debug e il rilascio di dcus funzionano correttamente?

D. È possibile superare l'errore originale se si passa alla cartella Win32 \ Debug e si elimina IdGlobal.dcu. Questo mi suggerisce che la compilazione del mio pacchetto (per debug config) sta producendo un IDGlobal.dcu NON VALIDO. È possibile? Can delphi emette silenziosamente DCU alterate?

Note: non sto utilizzando e non posso utilizzare i pacchetti di runtime per gestire i problemi relativi alle dimensioni dell'applicazione.

Aggiornamento: La prima cosa che avrei dovuto fare qui è verificare che ZERO altri file DCU siano OVUNQUE sul mio hard disk, OVUNQUE. Questo è il consiglio di errore standard di F2051. Aggiornerò questa domanda dopo essermi occupata di ciò. Sembra possibile che Delphi copra di per sé una DCU da un posto a un altro, o che una DCU falsa che NON è nel percorso di ricerca CORRENTE potrebbe essere stata in qualche altro percorso di ricerca del progetto. Può succedere una specie di brigata benna di copie difettose della DCU. Aggiornerò la domanda una volta che sono sicuro del tipo di cattiva generazione o di copie della DCU.

Aggiornamento 2: ora ho garantito che non esistono copie aggiuntive di IdGlobal.dcu prima della creazione e il problema si riproduce ancora. Pertanto, la domanda attiva le opzioni del compilatore utilizzate durante la creazione di IdGlobal.dcu, le versioni delle opzioni del compilatore utilizzate durante la creazione di BigApp.dproj in Debug build.

Aggiornamento 3: Anche se tutte le mie compilazioni di pacchetti sembrano complete senza errori, sembra che non stessero utilizzando un percorso di ricerca di libreria corretto, durante il momento in cui DCC32.exe o MSBUILD.exe viene avviato per creare i pacchetti. Questo problema di incoerenza del percorso della libreria sembra essere il problema principale, grazie a Sir Rufo per averlo indicato.

+8

Credo che ci sono alcune unità di debug compilati con "Usa Debug-DCU" impostato e gli altri non sono. Se impostato, il compilatore usa i file DCU da 'Debug-DCU-Path'. Quindi ora avete alcuni compilati con il debug-DCU di terze parti e altri no. –

+0

Perché sei così felice? Non l'ho mai capito. Perché non usare il tuo compilatore. –

+0

Perché l'IDE bds.exe utilizza un compilatore a 32 bit e consuma quasi 2 GB di memoria. Non è ben noto agli indirizzi e sta esaurendo la memoria. Circa 800 mega di essi sono generati dall'approccio di costruire TUTTO dalla fonte, e il resto viene consumato dal debugger quando carica i simboli. –

risposta

1

Ora capisco una fonte per questo problema. Per favore, manda su Sir Rufo come mi ha fatto pensare alla soluzione.

E 'questo: stavo invocando DCC32.exe per compilare pacchetti (usando .dpk, ma senza file .dproj, e non invocando msbuild per compilare questi pacchetti). Quando li ho creati, non inserivo il percorso Debug DCU in testa al percorso della libreria passato tramite i parametri -I a DCC32.exe.

Una volta che il percorso di ricerca della libreria di compilazione del pacchetto DCC32.exe ha le cartelle di debug DCU PRIMA, funziona.

Se qualcuno è interessato a un tale sistema di pacchetti, sto pianificando di aprire questo sistema di compilazione del pacchetto, come parte di un rilancio del progetto WANT originariamente costruito da Juancarlo Anez, che probabilmente chiamerò con un nuovo nome. Aggiornerò questa risposta una volta disponibile una demo funzionante di un sistema di creazione componenti.

una breve descrizione di un sistema di lavoro per soddisfare le esigenze ho chiesto nella mia interrogazione:

  1. Avrete bisogno di un file (potrebbe essere xml, ini, file di JSON) che definisce un elenco di pacchetti da costruire.

  2. Avrete bisogno di richiamare MSBUILD o DCC32.exe su ciascuno di questi. Potresti scrivere il tuo codice, o potresti usare il mio, che aprirò quando possibile.

  3. È necessario includere Debug DCROJ di debug nel percorso della libreria come primi elementi, SOLO quando si richiamano i build degli elementi di debug.

  4. Si desidera utilizzare la macro $(OURCOMPANYLIBRARYDCU)\$(Platform)\$(Config) nei percorsi di ricerca del progetto e nei percorsi della libreria.

  5. Nel proprio IDE Delphi, si desidera codificare il codice $(OURCOMPANYLIBRARYDCU)\$(Platform)\Release come percorso all'interno del percorso della libreria.

  6. Nel proprio IDE Delphi, è necessario codificare il codice $(OURCOMPANYLIBRARYDCU)\$(Platform)\Debug come percorso all'interno del percorso Debug DCU.

+0

C'era una domanda simile che mirava ai percorsi alcuni giorni prima di http://stackoverflow.com/questions/28425456/what-project-options-to-use-for-open-source-delphi-packages/28429240#28429240 –

+0

quel set di opzioni la risposta potrebbe essere abbastanza utile! grazie –

8

forse posso fare luce su ordine di sentieri di ricerca presentati al compilatore, che dovrebbe rendere chiaro il motivo per cui il problema si verifica in primo luogo e può essere curata (almeno nella vostra situazione) con l'aggiunta del Eseguire il debug del percorso DCU in quella posizione specifica. Tutte queste osservazioni sono state fatte con XE7.

ci sono molti posti nel IDE in cui è possibile specificare sentieri di ricerca:

  1. percorso della libreria (Delphi-Options - Library)
  2. Tradotto percorso della libreria (Delphi-Options - Library- tradotto)
  3. Debug DCU percorso (Delphi-Options - Library)
  4. tradotto Debug DC U percorso (Delphi-Options - Biblioteca Tradotto)
  5. percorso Ricerca (via Opzioni del progetto)

Quando la lingua Biblioteca è l'inglese, i sentieri sono indicati per il compilatore nell'ordine 5 , 1 o 3,5, a seconda dell'impostazione di Utilizzare debug .dcus. Questo è già un po 'strano perché il percorso di debug dcu ha la precedenza sul percorso di ricerca del progetto.

Quindi f.i. per fare in modo che il compilatore trovi i nostri file dcu di una nuova versione di Indy, dobbiamo posizionare i percorsi corrispondenti davanti ai percorsi sotto 1 e 3.

Ora le cose si complicano quando il linguaggio della Libreria è impostato su qualcosa di diverso da Inglese. In questo caso entrano in gioco i percorsi tradotti risultanti nell'ordine 2,5,1 o 4,3,2,5,1 a seconda dell'impostazione di Utilizzare debug .dcus.

Per eseguire l'esempio precedente con una versione di Indy più recente, è necessario modificare anche i percorsi tradotti.

Il colpevole si trova in CodeGear.Delphi.Targets, che posiziona i percorsi in questo ordine. Sono stato in grado di modificare questo file in modo da utilizzare l'ordine naturale dei percorsi: 5,2,1 o 5,4,3,2,1. Se qualcuno può confermare che sono autorizzato a mostrare questi cambiamenti, lo farò. Forse posso fornire solo una patch.

Aggiornamento: Qui ci sono i cambiamenti di CodeGear.Delphi.Targets da XE7 come mostrato da 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> 
+2

Penso che questo file target sia un file di configurazione e quindi dovresti essere in grado di mostrarne uno snippet. Anche un piccolo frammento del VCL rientra nelle leggi sull'uso corretto per mostrare una o due righe di. –

Problemi correlati