Link to home
Start Free TrialLog in
Avatar of GrahamDLovell
GrahamDLovell

asked on

Resolving inter-linked units in Delphi VCL

I have a multi-unit program, and have just started getting problems in compiling, with one of the units (an unchanged one) stopping the completion of the compile. Running the compile a second time fixes the problem.

I am not sure how to permanently fix. Is it:
1) related to the placement of uses clauses in the interface and implementation sections?
2) the order of the units in the project?
3) something else?
Avatar of MerijnB
MerijnB
Flag of Netherlands image

Can you reproduce this problem every time? If yes, how to break it and how to fix it?
Avatar of GrahamDLovell
GrahamDLovell

ASKER

It doesn't happen every time. The fix is to re-compile.
Make sure that your search path is ok (project option) and your unit is unique (not placed in more than one folder - just in app folder). Make sure that your unit is not circular attached to other unit(s) (unit A uses unit B and back...) . Units are compiled when compiler decide to - ex. some of depending unit is changed. Think that order in uses will not solve this - but position - implemntation uses and main uses - maybe.
What error message do you get when it does not compile?
Sinisa:
Yes, I reckon that interface / implementation uses clause placement is important, but I don't know the rules. Is there a reference somewhere for this?
Circular references seem to work OK, provided you get the uses clause correctly placed in each; e.g. uMain (the first unit opened) calls procedures in all the other units, and the other units call procedures in uMain. It seems to work if I put uMain in the interface uses clause of these other units.
Delphi seems to be quite good at sorting this out, most of the time.
I have also just changed the file order in the project manager to put the unit that gets most (if not all) of the complaints lower in the list than the units it calls. This might have fixed it, but if so, I don't know why, since other units compile when the same condition applies.

MerijnB:
I get a top level message, something like - could not compile "unit name", but no reason. It doesn't happen every time I make a change.
Is it possible you have antivirus or backup software which has an open file handle to the dcu which is being recompiled?
No. An immediate re-compile resolves the issue, without doing anything else.
Backup is out; it was not running. In addition, if it were random, it could not be seen to affect at most a couple of units or repeated occasions.
If this is caused by any software having an open file handle that could very well mean that it's solved when you compile it again (you just have bad luck that there is a file handle open at the first time you compile).
What can I say? I anticipated that response, and thought I had answered it. Why would a random event repeatedly attack a single unit (or a couple of units - I cannot remember all the examples) when those units have not been changed.
Ok, just wanted to make sure you made that thought process :)

What Delphi version are you using?
XE6
All I can think of now is to make this problem as small as possible. You will probably find something interesting at the point where you can't reproduce it anymore.
Have you consider to rewrite unit to avid circural reference. Unit A can do uses unit B, but when Unit B needs something from A - use address of callback function. Definition of callback function can be in third unit C.
ASKER CERTIFIED SOLUTION
Avatar of GrahamDLovell
GrahamDLovell

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
circular unit referencing should be avoided
it can work, but the effects you get are perfectly normal when having common units across different apps
especially if they use the main form

i suppose you have common units among different projects ?

do you fix the problem with compile or build ?
build does a bit more.
you can also have very nasty behavior when using compiler directives in common units
you'll get errors when compiling and have to rebuild

i don't know the exact syntax for compiler directives, but here is the pseudo code:
common unit ABC;
{$IF NOT DEFINED XXX THEN $DEFINE XXX=1}

project X1
does not have compiler directives
> unit ABC is thus compiled with XXX=1

project X2
has compiler directive XXX=2
when compiling X2, it may throw an error as it tries to find info which is hidden for all items with compiler directive XXX=1
rebuilding the X2 project solves this problem

if you want help on solving circular unit reference problems ... just
your best option, but not the fastest and easiest, is to solve the circular unit reference
As far as I can tell, this problem is not one of circular references, but rather of compile order. The unit which appears in the compiler complaint is quite small, and I can't see a circular reference.
Fixing the order of units in the project fixed the problem, but I have don't have a clear understanding of why it worked.
if you override a class and change the order of the units ... it can cause problems

sometimes adding windows unit without explicitly using something from it can cause that too