HNRSoftware
HNRSoftware

Reputation: 81

How do I Organize Shared Units in modern Delphi?

For over a decade, I have been stuck (lovingly) on Delphi 6 and have developed hundred of thousands of lines of code in a logical (to me) unit structure, where a project tends to be a few hundred lines of code referencing high-level work routines in my "library". In trying to migrate to XE5, I just can't find a way to have all my library units compiled in one place on the search path, and then just used by the project (and recompiled if necessary), but that the dcus are off with the library source rather than in with each individual project.

I'm just starting to accept that "hello world" takes 2.5Mb in XE5, and I can't stand the idea that each library unit has to be separately compiled into dcus at the project level. In the "old" days, these unit dcus would sit next to the pas files and not be recompiled if nothing changed in the source file.

The obvious place to look is the Project options, but I can't find the right setting to make the project stop keeping copies of each dcu.

I am vaguely aware that multi-platform development will cause restructuring, but I can't help feeling that there is some compromise position.

There must be something big I am missing.

Upvotes: 6

Views: 1386

Answers (2)

HNRSoftware
HNRSoftware

Reputation: 81

First, let me thank all the respondents to this question - all provided useful insight. I experimented with the various suggestions (including breaking XE5 so badly that I had to reinstall -- at least I learned some areas not to mess with.)

  1. Important to me, but a known bad coding practice, is having individual projects edit shared library units (only my own units - I do not mess with code belonging to Delphi or 3-rd party). This is critical to having multiple applications working on the same data, but in bite-sized pieces. the shared code lets me make high-level pieces of an app available to other projects. There might be better ways (I would love to hear about them), but this has worked for me for a long time.

  2. The multi-platform model really requires the dcu structure used by default, so I will adapt to it. Share the source code, but accept multiple compilations to individual projects. A good suggestion by JensG is just to clean up the dcus when the project is not actively being worked on. Should be straight-forward utility program.

  3. The D6 -> XE5 migration (which will take months for some of the less used areas) requires me to know which units compile successfully, so I will maintain one project whose function is to include all units and recompile them all. This will make it practical to map library unit pas files to dcu files.

  4. The AnsiString/AnsiChar <-> String/Char problem is the major migration problem area. Simply making edit-level changes may get the code past the compiler, but there is no guarantee that the code still works the same way. Especially troubling is at interface points to Windows calls and such. My answer will be to make the units compilable first, but then write test code for trouble areas. This is what will take the months - I need to get on with new stuff, as well as fixing the old. I REALLY don't know yet if I will be able to substitute the XE5 compatible code back into Delphi 6 without another layer of testing. I THINK it should work, but it will take careful checking.

  5. A second major migration problem is 3rd party code such as VCLZip. XE5 has its own zip support, but I have a lot of places where I use VCLzip and the conversion will not be trivial. For this specific library, it may be possible to find XE5-level source and simply work it in. There are other pieces of code gotten from the internet that I used, but never needed to truly understand which will cause significant hassles.

Again - thank you to all. This has been an interesting 24 hours. Howard

Upvotes: 0

Jerry Dodge
Jerry Dodge

Reputation: 27296

Starting in Delphi XE2, Delphi supports compilation for multiple platforms, as well as different build configurations. Because of this, Delphi needs to create DCU files for each combination. For example, Win32, Win64, and OS-X DCU files are saved in separate folders by default. Otherwise, if it weren't like this, the DCU files would overwrite each other, which you should avoid (if you use different configurations/platforms).

These settings can be changed in the Project Options in the very first section Delphi Compiler by modifying the Unit output directory. This is by default .\$(Platform)\$(Config) which creates a subfolder for the platform, then another subfolder for the config, for example \Win32\Debug\. Careful for the Target at the very top, which by default is set to your current platform/config. You would typically want to first change it to All Configurations. If you clear this field completely from the options, it will produce your default behavior from older versions.

It sounds like you should create a Package. This would allow you to group all your "library" units together in one place (BPL). This package can then be installed into your IDE, and if you have any components, those components can then be installed into your component pallet.

Or you can do without a package too. All the units from all these different projects should be moved to this central place though - a single folder containing all your "library" units. This way it's less maintenance, and you can just add that one folder to your global library path.

If you put your files in a central folder, and use those files from a project, the DCU files for both the project and this "library" will be saved for that project. Delphi doesn't know that these files are a "library", it just knows that you're using them, and since it can't find an already compiled version of those units, it creates one in your project. If you want the DCU files to be saved only once and in this central place, then you would need a package.

Upvotes: 1

Related Questions