VSoft Technologies Blogs

rss

VSoft Technologies Blogs - posts about our products and software development.

We use many third-party Delphi libraries to build FinalBuilder and Automise, and that brings plenty of issues when upgrading compiler versions. I've been using Delphi since 1995, both as a developer and as a component vendor, I have learned a thing or two about creating libraries that I would like to share. These are all ideas that make life easier for users, and make it easy to migrate from one version of Delphi to another.

There's no hard and fast rules on how Delphi Libraries are supposed to be structured, these are just my preferences and things I have learned over the years. Hopefully this will help new and existing library authors.

Folder Structure

Keep the Source and the Packages in separate folders, this makes it easier to find the correct packages to compile, e.g :

\Source
\Packages
\Demos

Under Packages, create a folder for each compiler version your library supports, e.g:

\Packages\Rad Studio XE8
\Packages\Rad Studio 10.0
\Packages\Rad Studio 10.1

Package Names

Please, do not put the Delphi version in the package project names.

Bad!!!

MyProjectRun_D10_4.dproj
MyProjectDesign270.dproj

Good

MyProjectRun.dproj
MyProjectR.dproj
MyProjectDesign.dproj
MyProjectD.dproj

Why not put the compiler version in the package project name you might ask? Well the answer is that it makes upgrading compiler versions a major pain for users who link their projects with Runtime Packages (yes, that includes us).

The reason is that when you compile a package, it creates a packagename.dcp file and that is what your project references. So, if your package name is MyPackageRun_D10_4 then that is what will be added to projects that use it.

package MyOwnPackage;
//...
requires
  rtl,
  vcl,
  MyPackageRun_D10_4,
  AnotherPackage_Sydney,
  YetAnotherPackage_D104,
//  ...
        

When Delphi 10.5 comes out, guess what the user has to do to upgrade their projects.... Yep, replace that all those package references with 10.5 versions (and the multitude of suffixes). Multiply that by a number of projects and a number of libraries (each with potentially multiple runtime packages) and you can see why this might be a pain.

Now you might say, but we don't want 15 versions of MyPackageRun.bpl laying about on users machines, and you would be right. The solution to this is a feature that has been around since Delphi 6 (2001) - LIBSUFFIX.

LIBSUFFIX

Setting LIBSUFFIX (on the Description section of project settings) will append the specified suffix to the BPL file name. So a suffix of _D10_4 will result in a package :

MyPackageRun_D10_4.bpl

however, the DCP file will still be generated as :

MyPackageRun.dcp

Remember it's the dcp file that our projects reference (for linking) - so by keeping the dcp file the same for all delphi versions, upgrading to a new compiler version just got a whole lot easier!

So when Delphi 10.5 comes out in the future, all I need to do is install the packages, no changes to my projects.

Update : Someone pointed out that Delphi 10.4.1 support LIBSUFFIX $(Auto) - this will use the Delphi defined PackageVersion - which for 10.4 is 270. This is a nice addition as it makes upgrading the package projects simpler. Of course if you don't like the PackageVersion suffix and use a custom one, then this is not for you.

Use Explicit rebuild, not Rebuild as needed

Have you ever encountered the error

E2466 Never-build package 'XXX' requires always-build package 'YYY'
What this means is, a package, set to Expicit rebuild, references another package, set to 'Rebuild as needed', and it's a pain in the proverbial. Rebuild as needed is also referred to as Implicit Build - in dpk's you will see it as
{$IMPLICITBUILD ON}
If that "Rebuild as needed" package is not part of your project group, guess what, you get to waste time closing and opening projects trying to get it to compile.

I'm sure someone will correct me on this, but I cannot see a good reason to have "Rebuild as needed" set. I suspect this is a hangover from before the Delphi IDE allowed you to specify Project Dependencies and it slows down builds.

Use Search Paths for includes

I often see includes with either hard coded paths, or relative paths like this :

{$I '..\..\MyDefines.inc'}
        

That's great, if the installer delivers the files in the right place - but they often don't - I hit this issue today, where the package just would not compile. I eventually figured out that the relative path was wrong.

There's a simple fix for this, and that is to remove the path in the $I statement, and use the Project Search Paths feature instead.

Search Paths

I have also seen libraries where there are mulitple copies of the include file and they are slightly different!

Mark packages as Runtime only or Designtime only

Some libraries have their packages marked as "Runtime and Designtime" (the default) - the impact of this is only minor, but it's a pet peeve of mine. The Delphi IDE (in recent versions at least) provides a nice indication of whether packages are runtime or designtime in the project tree, and for designtime packages, whether they are installed.

This makes it simple for me to determine which ones need to be installed or not.

Not Installed

Not Installed

Installed

Installed

Summing up

One of the major reasons people do not upgrade Delphi versions is because it's too hard to deal with the third party libraries and all the changes required just to get to the point of compiling. That eventually results in a lack of Delphi sales which results in a lack of investment in Delphi which feeds back into.... well you get the idea ;)

Making third party libraries easier to work with in Delphi has been a bit of a crusade for me, I've been working on this for a while now, and I'm getting closer to a solution - DPM - A package manager for Delphi - if you are a library author, I encourage you to take a look. For examples on how to create a package spec (dspec) take a look at our open source projects https://github.com/vsoftTechnologies/

Showing 1 Comment

Avatar
David Moorhouse 4 years ago

That's a great reminder Vincent, and also applies to in-house component/code libraries that developers create for their own use.



Comments are closed.