Iâm a (fairly) new Pascal user, and I am trying to help a friend port a Digital Pascal application to GNU. I am now looking at one of two âbig (?)â programs, which contains about 3000-4000 functions/procedures in about 40 modules. Currently, this is organized as follows: There is one âenvironmentâ module (which every other module âinherits,â) containing type definitions, global variables, and a list of â[global]â functions and procedures, declared (here) as âexternalâ. All functions/procedures used in the set of modules are [global], and they are (or at least seem to be, at this point,) more or less randomly distributed over the 40 modules, (so that a proc/func from any module might be calling a proc/func contained in any other module.)
I have tried using the unit / uses syntax, (specifying that each unit âusesâ this environment module,) but I still cannot get these units linked. The compiler is complaining about several hundreds of âundefined referencesâ â I am now assuming that it is expecting the âimportedâ modules to contain the code for all of the procs/funcs called by each unit, rather than just the âexternalâ definition. Is this correct, or might I be misunderstanding what is happening? (I am currently running gpc-20040516, gcc-3.3.3, on Suse Linux. I had previously run some tests using the last Gnu Pascal release system running on cygwin.)
I am hoping to avoid having to analyze dependencies and completely re-organize the modules. Is there any other way?
Thanks for your help, - Inga Matthews
Mingeborg@aol.com wrote:
I have tried using the unit / uses syntax, (specifying that each unit “uses” this environment module,) but I still cannot get these units linked. The compiler is complaining about several hundreds of “undefined references”I am now assuming that it is expecting the “imported” modules to contain the code for all of the procs/funcs called by each unit, rather than just the “external” definition. Is this correct, or might I be misunderstanding what is happening? (I am currently running gpc-20040516, gcc-3.3.3, on Suse Linux. I had previously run some tests using the last Gnu Pascal release system running on cygwin.)
I am hoping to avoid having to analyze dependencies and completely re-organize the modules. Is there any other way?
I don't know if you've already got an answer, so here's mine:
Could you send a detailed error message from the compiler? It's especially interesting which references remain unresolved.
My guess is that you are using some of the GPC standard units, and that you didn't add the according linking statements to the command line. For example, if you're compiling a source that "uses Crt", your command line will have to look like this:
gpc foo.pas -o foo -lncurses -lpanel
... since crt.pas is based upon the shared libraries libncurses and libpanel.
Regards,
Markus
Markus Gerwinski wrote:
My guess is that you are using some of the GPC standard units, and that you didn't add the according linking statements to the command line. For example, if you're compiling a source that "uses Crt", your command line will have to look like this:
gpc foo.pas -o foo -lncurses -lpanel
... since crt.pas is based upon the shared libraries libncurses and libpanel.
It shouldn't have to (if you're using automake or GP) since the units contains the `{$L}' directives (appropriately ifdef'ed -- the version above only applies to Unix/terminal, also it needs crtc.c).
Mingeborg@aol.com wrote:
I am enclosing a gzipped tar file of 5 very small example files, (test.tar.gz.)
This is the example code:
unit env; interface procedure proc1;external; procedure proc2;external; procedure proc3;external; implementation end.
unit unit1; interface uses env; procedure proc1; implementation procedure proc1; begin writeln("running proc1"); end; end.
Digital Pascal allows this "structure" of the code via [global] modules, and this code worked in the last release.
Well, you declare procedures `proc' in `env' and `unit1', and these two do not necessarily have any relationship, except that they have the same name (but in different units).
In fact, I wonder how the other compiler does it -- I suppose either it doesn't support using the same identifier in different units for different purposes completely (GPC doesn't either, but will soon, with Waldek's qualified identifier changes), or it treats them as separate and throws them together at link time.
Well, GPC can do the latter as well, but you have to tell it to explicitly:
[env] procedure proc1; external name 'proc1';
[unit1] procedure proc1; attribute (name = 'proc1');
I still don't consider it very nice.
The "real" solution would, of course, be to declare all routines in the interface of that unit which implements it, and get rid of your `env' unit.
Then, each unit can import (`uses') all other units (or only those that it actually needs) in the implementation part, so you can compile all interfaces first, then all implementations (or use GP which will do this automatically).
Frank
Markus Gerwinski wrote:
[snip]
Digital Pascal allows this "structure" of the code via [global]
modules, and this code worked
in the last release.
[snip]
The "real" solution would, of course, be to declare all routines in the interface of that unit which implements it, and get rid of your `env' unit.
Then, each unit can import (`uses') all other units (or only those that it actually needs) in the implementation part, so you can compile all interfaces first, then all implementations (or use GP which will do this automatically).
I happen to be porting code originally in DEC Pascal. This code has also gone via Turbo Pascal & something other thing I forget to GPC so it doesn't _quite_ apply. (In fact at some point I'm going to have to completely overhaul it as its been through one too many "quick ports" to my mind... :-) )
I'd second Franks suggestion of discarding the env unit; this is essentially how my code is structured, save for one nuisance I had to work around. For all the things declared [global] in any one module I make up a little global unit for that module, then use 'use' to bring them back in. This way they can be 'use'd by several units and maintain the overall code structure.
FWIW, this relates to 'uses inheritance' thing I raised ages ago which caused (too) much fuss. If interfaces where inherited you wouldn't have to do this, you'd just 'use' the module and that'd be it. But we've been through that and GPC doesn't do this :-)
Grant