From: Berend.de.Boer@p23.f112.n100.z60.wlink.nl (Berend de Boer)
Newsgroups: comp.lang.pascal
Subject: TP and large project
Date: Thu, 08 Oct 1992 10:22:04 -0100

GANG FANG wrote in a message to All:

 GF> Hi everyone:
 GF> 	We are currently working on a fairly large project. The
 GF> program is  written in TP 6.0. The final .EXE is made from
 GF> about 100 .TPUs. We are having  serious problem compiling
 GF> the program. Whenever a change is made to some  modules,
 GF> especially those heavyly used by other modules, we'll get
 GF> all kinds of  error messages when compiling the program,
 GF> like 'circular reference, too many  open files, too menu
 GF> nested files' etc. We played all the tricks that we know 
 GF> like incresing 'FILES=' in config.sys, compiling individual
 GF> modules instead of  compiling the main program etc. but
 GF> still can't solve the problem. The  situation is getting
 GF> worse as the dependencies between modules increases, it's 
 GF> totally out of control. Redesign the program is almost
 GF> impossible can someone  provide a reasonable solution to
 GF> this problem?

Hello Gang Fang,

As I recognize your problem (with 70+ units), I have four options. You
can choose any or a combination of them.

First the cause: this is IMHO not a flaw of Turbo Pascal but a design
flaw. I suppose that the following occurs: you have one or more units
in which you define (in the inerface section) "global" types and/or
constants AND global variables with a type depending on other units
which use these units with global types and vars.

1) units referring to each other in the interface section is
   impossible. You have to remove these dependencies by creating new
   units or moving code and/or types/consts/global vars;
2) units referring to each other with an intricate referencing to each
   other via interface uses clauses and implementation uses clauses
   cause the compiler to complain about dependencies which do not have
   to exist. I assume this to be your case.


Advice 1
--------
Place global variables with types depending on a type definition in
some unit which has that unit with the global variables in its
implementation uses clause in the unit where you have the type
definition.
Place global types in one unit. This unit may not refer to units that
refer to this unit.

Some kind of redesign is necessary to eliminate the cause of circular
(at least for the compiler) dependency completely.


Advice 2
--------
Use the make utility. Your program cannot simply be compiled by

  tpc /m /l main

This is due to the serious design flaw(s) in your program as I believe
(as with my program). You can work around it by making clear the
dependencies to the make utility. You probably will see that after
some fiddling with make, TP compiles some units twice or more (because
of the circular design).
You have first to compile some units seperately before you can compile
the main program. This will eliminate (for the compiler) the circular
design.
Heuristic approach for making clear dependencies (I do not know if
this works for you, but it did for me):

a) Compile the main program. Compiling will stop with a circular unit
   reference in ..
b) Compile that unit. If you get another circular reference, go to
   that unit and compile until you do not get anymore errors
c) so you found a unit which has to be compiled before your main
   program can be compiled
d) Compile again your main program
e) etc. In this way you detect the units which have to be compiled
seperately before the main program can be compiled

If you follow this approach I like to know the results as I do not
know for sure if this works.


Advice 3
--------
Move type definitions to units that are referring to other units for
types and/or consts to that unit to minimize dependency. Only an
emergency advice.


Advice 4
--------
And now the how-do-I-become-a-C-programmer-trick for unit
dependencies. You can remove dependencies by moving units from the
interface section to the implementation section. I assume that units
in the interface section are mostly there to provide predefined types.
Example:

unit MyType;

interface

type
  rectype = record
              str : string;
              w : word;
            end;

....

end.


unit Dependent;

interface

uses MyType;

procedure MyProc(r : rectype);

...

end.


Now remove the interface dependency by the following unadvised trick:

unit Dependent;

interface

procedure MyProc(var r);

...

implementation

uses MyType;

procedure MyProc(var r);
var
  myr : rectype absolute r;

{* refer not to r but to myr in this unit *}
...

end.


The last two advices are NOT recommended.

 GF>    Thanks in advance for any response.

Hope this helps.


Greetings, ...... === Ent ===

berend.de.boer@contrast.wlink.nl
Xref: sparky comp.lang.pascal:5948 comp.lang.modula2:1265