Advice for Delphi library authors
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.
\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
MyProjectDesign270.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.
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) - Для просмотра ссылки Войдиили Зарегистрируйся.
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.
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 Для просмотра ссылки Войдиили Зарегистрируйся and it slows down builds.
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.
I have also seen libraries where there are mulitple copies of the include file and they are slightly different!
This makes it simple for me to determine which ones need to be installed or not.
Not Installed
Installed
Making third party libraries easier to work with in Delphi has been a bit of a crusade for me, I've been Для просмотра ссылки Войдиили Зарегистрируйся, and I'm getting closer to a solution - Для просмотра ссылки Войди или Зарегистрируйся - 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 Для просмотра ссылки Войди или Зарегистрируйся
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.dprojMyProjectDesign270.dproj
Good
MyProjectRun.dprojMyProjectR.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,
// ...
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) - Для просмотра ссылки Войди
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.
Use Explicit rebuild, not Rebuild as needed
Have you ever encountered the errorE2466 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 Для просмотра ссылки Войди
Use Search Paths for includes
I often see includes with either hard coded paths, or relative paths like this :
Код:
{$I '..\..\MyDefines.inc'}
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.
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
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 ideaMaking third party libraries easier to work with in Delphi has been a bit of a crusade for me, I've been Для просмотра ссылки Войди