There appear to be some quite extensive memory limitations in the DCAL compiler. I have come across the ''Unable to add external reference' all too often, but I can't say I'm familiar with the 'Doubly defined error' message.
I assume you are compiling/linking with the dcc1 & dcc2 commands (rather than the one-step dcc command). If not, that is the first thing to try.
You may also want to take a look at the environment where you are doing the compiles. Obviously the compiler does not work at all on 64 bit systems, but it appears to me that some of the more recent 32 bit Command Line implementations left less memory heap available for the running application than the earlier versions of MS-DOS. I use DOSBox
for any DCAL compiles I need to do not only because it allows me to run the compile on a 64 bit machine, but also because it appears to be quite a lean DOS implementation (dcs files that get a heap overflow error in a Command Line window on my old Win 7 laptop will compile without problem using DOSBox on my Win 10 machine)
I have never bothered to try to come up with the actual numbers, but there is certainly a limitation on the number of external calls that you can have in a single dcs file (I've never realised that this also applied to BUILTIN procedures, but obviously you have found a limitation there also).
There are 2 ways around this limitation:
1. You can split your single dcs file into multiple modules. My SpacePlanner macro ended up with over 20 separate modules as a result of the need to do this ... this then caused problems with the DCL linker which appeared to only recognise the first 128 characters of the command line parameters (I initially thought this was a DOSBox limitation but I am by not means certain ... it may be a limitation of the DCL compiler itself or even a DOS limitation ?? ... it occurred even when using a .lnk file). The result of this command line limitation was that I needed to shorten the names of my source files so that I could fit all their names in 128 characters (e.g. 'SPlanner.dcs' became 'SP.dcs' and so on).
2. Rather than having multiple calls to the same external procedure you can create a local procedure that calls the external one and then call that local procedure from multiple places in your code. I used this approach for much of my logging logic in Space Planner and an example code snippet is shown below:
Code: Select all
PROCEDURE MyLogStr (str : string);
! Added this proc to reduce number of external references
In the above example LogStr is an external call, but I only call it once (in the code shown). There are then multiple calls to MyLogStr thoughout the code.
I have also found that sometimes
a linker error can be solved by changing the order of the modules in the dcl parameters. This is pretty much a last resort and in most cases will not fix a problem (but on occasion it has worked when all else fails).
I hope you manage to get around all the DCAL compiler/linker limitations, but those limitations (and the logical gymnastics you sometimes have to go through to get around them) are certainly one of the reasons why I have turned to D4D for any particularly complex macro development (although I think there is still a place for Classic DCAL as it can do a few things that D4D cannot ... see the comparison page on my website