Jump to content
aehimself

Splitting existing components to run- and design time packages

Recommended Posts

I like to compile my components and let Delphi use the existing DCUs in my projects. Having my sources on SSD this not just saves time but prolongs the life of the data store as well.

I recently started to experiment with a component suite which was written as a blob, runtime and design time in one, therefore I can not build 64 bit DCUs.

 

I never really thought of creating my own component packages and therefore I have 0 experience with this. Are there any tips, tricks or resources that can help me achieving my goal? At the moment I can't even tell how to distinguish what is considered runtime and what is designtime 🙂

Share this post


Link to post

There is a page in the Delphi wiki on creating packages.

https://delphi.fandom.com/wiki/Creating_Packages

 

Edit: I had totally forgotten that I wrote that page myself (many years ago). After reading through it, I must say I still like it. There isn't much I'd change today.

Edited by dummzeuch
  • Like 3
  • Haha 1

Share this post


Link to post
Quote

At the moment I can't even tell how to distinguish what is considered runtime and what is designtime 

Hopefully the experts will comment further.  Custom components need to have unique names and learning how packages work use a project group.     

Share this post


Link to post
2 hours ago, aehimself said:

I like to compile my components and let Delphi use the existing DCUs in my projects. Having my sources on SSD this not just saves time but prolongs the life of the data store as well.

 

🙂

I use ramdisk for .dcu. Really fast and it is clear after reboot, so I do not have problems with outdated .dcus found somewhere.

Share this post


Link to post
4 hours ago, aehimself said:

I like to compile my components and let Delphi use the existing DCUs in my projects. Having my sources on SSD this not just saves time but prolongs the life of the data store as well.

I don't get this at all. I've got a Mac Mini and MacBook Pro from 2014 with only SSD and thousands of hours of use, and have had no problem with either one. 

The best way to prolong the life of your equipment is to not use it. Next to that, drive it until it dies, then replace it. Fortunately or unfortunately, Apple's hardware seem to last a very long time. (I did have to get the base of my MBP replaced because the battery started bloating up; they salvaged the main board and top cover and display, but replaced the rest of the base including the keyboard.)

Share this post


Link to post
12 hours ago, dummzeuch said:

There isn't much I'd change today.

Not even the part that's wrong?

 

Quote

This is not the correct way to write packages, as even Borland says somewhere in the online help (look it up, it's there!).

 

Share this post


Link to post
8 minutes ago, Anders Melander said:

Not even the part that's wrong?

Ok, what is wrong with this:

9 minutes ago, Anders Melander said:

This is not the correct way to write packages, as even Borland says somewhere in the online help (look it up, it's there!).

Are you sure it's not there (I think I looked it up back then, but my memory might be faulty). Or are you referring to mentioning "Borland" rather than "Embarcadero"?

Share this post


Link to post
11 hours ago, Vandrovnik said:

I use ramdisk for .dcu. Really fast and it is clear after reboot, so I do not have problems with outdated .dcus found somewhere.

RAM disks... Didn't we stop using those along with DOS and Windows 95?

Of course a dedicated physical RAM disk device will always be faster than an SSD but if you're allocating main system memory for use as a virtual RAM disk device then I think it would be better to let the OS manage the memory. It will use the memory to cache files when the memory isn't needed elsewhere.

Share this post


Link to post
10 hours ago, David Schwartz said:

I don't get this at all. I've got a Mac Mini and MacBook Pro from 2014 with only SSD and thousands of hours of use, and have had no problem with either one. 

The best way to prolong the life of your equipment is to not use it. Next to that, drive it until it dies, then replace it. Fortunately or unfortunately, Apple's hardware seem to last a very long time. (I did have to get the base of my MBP replaced because the battery started bloating up; they salvaged the main board and top cover and display, but replaced the rest of the base including the keyboard.)

* Sigh *

Share this post


Link to post
45 minutes ago, Anders Melander said:

RAM disks... Didn't we stop using those along with DOS and Windows 95?

Of course a dedicated physical RAM disk device will always be faster than an SSD but if you're allocating main system memory for use as a virtual RAM disk device then I think it would be better to let the OS manage the memory. It will use the memory to cache files when the memory isn't needed elsewhere.

From 18 GB RAM, 0,5 GB is dedicated to RAM disk, so this is negligible... I prefer to write .dcus there, so that it does not write again and again to SSD, it is faster and .dcus are always fresh.

  • Like 1

Share this post


Link to post

So back to the original topic I went ahead and created the two packages based on the article @dummzeuch shared. I coped everything from the original package to this, changed the platform to Win64 and moved the parts what caused the compilation to fail to the design time package (Only design time editors and registration procedures). It worked 🙂

 

I was finally able to build 64 bit DCUs but then I realized that my design time package contains only ~4-5 of the 20 components. A quick search showed that there are still at least 40 files with RegisterComponents call in my new runtime package, but it still compiles... is this normal? 🙂

Share this post


Link to post
1 minute ago, aehimself said:

A quick search showed that there are still at least 40 files with RegisterComponents call in my new runtime package, but it still compiles... is this normal? 🙂

Yes it's normal that it compiles. RegisterComponents is a regular function located in the classes unit and if you couldn't use classes.pas from a run-time package then you couldn't do much at all.

 

You don't necessarily need to have both a run- and design-time package (yes, there are different opinions on that) but if you have decided to split the packages into run- and design-time then I guess you should move the RegisterComponents into separate registration units and place those in the design time package.

  • Like 1

Share this post


Link to post
16 minutes ago, aehimself said:

I coped everything from the original package to this, changed the platform to Win64

Waitamoment! You can't make a 64-bit design-time package. The Delphi IDE is 32-bit so design-time packages needs to be 32-bit.

Edit: Okay I need pay better attention. I can see you've already figured this out.

 

If you already have all the components registered in the original (design- and run-time) package then why are you even bothering with creating a new package? Are you actually using run-time packages?

 

It sounds more like your project is misconfigured if it needs precompiled dcus (e.g. from compiling a package) in order to compile.

Edited by Anders Melander
too much coffee

Share this post


Link to post

@Anders Melander I don't yet have a real-world project which is using this. I only wanted to be able to generate the 64bit DCUs so when a project will use this component, it won't compile the component from source again.

 

I guess I'll have to move all RegisterComponent calls to the design time package, am I on the right track? I guess it belongs there.

Share this post


Link to post
1 minute ago, aehimself said:

I only wanted to be able to generate the 64bit DCUs so when a project will use this component, it won't compile the component from source again.

Bad idea IMO.

Sharing DCUs among projects only leads to problems in my experience. When I do a clean build I want everything built from scratch, with the options I have enabled at that time. I don't want the compiler to link in some old DCUs that were compiled with god knows what options.

 

2 minutes ago, aehimself said:

I guess I'll have to move all RegisterComponent calls to the design time package, am I on the right track? I guess it belongs there.

You don't need to (as I explained) but it's cleaner design to separate design-time code from run-time code.

  • Like 1

Share this post


Link to post
3 minutes ago, Anders Melander said:

You don't need to (as I explained) but it's cleaner design to separate design-time code from run-time code.

This is exactly what I meant, yes, thank you 🙂

Share this post


Link to post
21 minutes ago, Anders Melander said:

Bad idea IMO.

Sharing DCUs among projects only leads to problems in my experience. When I do a clean build I want everything built from scratch, with the options I have enabled at that time. I don't want the compiler to link in some old DCUs that were compiled with god knows what options

Are you rebuilding whole VCL&RTL as well every time you build a project? ))) You're reinsuring here IMHO. Moreover, components could likely have special compiler options set in package file.

 

Edited by Fr0sT.Brutal

Share this post


Link to post
41 minutes ago, Fr0sT.Brutal said:

Are you rebuilding whole VCL&RTL as well every time you build a project? ))) You're reinsuring here IMHO.

Actually there was a time (in the 1990ies) when we did exactly that: Recompile the whole VCL/RTL in our projects. Mostly because we had to fix some bugs. These bugs were fixed by Borland (Yes, there was a time where this happened quickly.), so we stopped doing that. It also became impossible to simply recompile the RTL because it required some assembler.

 

As for components: Yes, I still compile them from sources in programs that do not use packages. I want to be sure that the source code I see while debugging is the actual source code used in the program. Given Delphi's compile speed it doesn't really matter much. But we degrees. Of course every program has its own dcu output path. Sharing that between multiple programs is a really bad idea.

  • Like 2

Share this post


Link to post
4 hours ago, dummzeuch said:

Ok, what is wrong with this

I'm not sure what you are referring to there, but I was referring to the statements that:

  1. It's wrong to have the TMyButton class and the Register produce in the same unit.
  2. You need to have both a design- and a run-time package.
  3. This requirement is documented.

 

4 hours ago, dummzeuch said:

Are you sure it's not there (I think I looked it up back then, but my memory might be faulty).

Yes. I'm sure.

In one of the many discussions I've had with Remy on this topic I checked the documentation all the way back to Delphi 1 and nowhere does it state that one must (or should) have both a design-time and a run-time package. I have also failed to find any other authoritative sources for the claim. It's always something that people heard from a friend of their 2nd cousins yoga teacher - or something like that 🙂

 

My claim is that, unless you link with run-time packages or share code between design-time packages, it's perfectly acceptable to put everything into a design-time package if you can. I.e. you don't need the run-time package.

This also makes creating and maintaining design-time packages so much easier.

  • Thanks 1

Share this post


Link to post
Quote

My claim is that, unless you link with run-time packages or share code between design-time packages, it's perfectly acceptable to put everything into a design-time package if you can. I.e. you don't need the run-time package.  This also makes creating and maintaining design-time packages so much easier.

Design package DX still makes a BPL.   Can the .dproj help switching the packages from 32 to 64 or hide them in mmx.       

Share this post


Link to post
3 hours ago, Anders Melander said:

Bad idea IMO.

Sharing DCUs among projects only leads to problems in my experience. When I do a clean build I want everything built from scratch, with the options I have enabled at that time. I don't want the compiler to link in some old DCUs that were compiled with god knows what options.

I did not really make components up until this point - maybe that's why I never faced an issue you are talking about. But if I'm not contributing to a component the practice of "download / update -> rebuild DCUs -> ??? -> profit" always worked for me.
It seems being the end user has it's benefits sometimes 🙂

Share this post


Link to post
1 hour ago, Pat Foley said:

Design package DX still makes a BPL.   Can the .dproj help switching the packages from 32 to 64 or hide them in mmx.  

I have no idea about what you are asking. Please rephrase the question.

Share this post


Link to post
2 minutes ago, aehimself said:

I did not really make components up until this point - maybe that's why I never faced an issue you are talking about.

Components has nothing to do with it. What I'm saying is that if you have your aeSuperDuperUtilities.pas unit, and you use that unit in different projects, then don't compile it in one project and use the DCU in another. It's okay to share the source file between projects (it would be better if you didn't, but that's another matter) but don't share the DCU files. Let each project have their own DCU output folder and don't use precompiled DCUs (the VCL/RTL being the exception).

Even for something as huge as DevExpress (1700 DCU files, ~370 Mb) I never use the precompiled DCUs.

 

I don't care about the minor improvement in compile speed sharing DCUs can give me. I do care about the time that is wasted when I have to track down some obscure problem caused by using out of sync DCUs.

Share this post


Link to post
Guest

Here is a particular case from developer to developer!


By default, tasks should be divided, even when creating packages (without them commercial or not), so that maintenance is easier in future versions or editions!

 

So spoke the Borland gurus, at their peak!

 

Now in practical examples, let's look at the behavior of two well-known companies of Object Pascal programmers and users, aka Delphi!

 

TMS softwares (www.tmssoftware.com) makes use of the technique of encompassing both Design-Time packages and Run-Time packages, generating only one BPL and with the option of "Install", however,

packages directed to the 64-bit platform, they are compiled just by changing the "Target Platform", and, there are 2 units to register the components / classes: one for Design-Tiem, and another for Run-Time!

 

image.thumb.png.1e324cc61a4eb8def42580f6c7a24429.png   image.thumb.png.998ae6c806e473f43eaf73c373942b71.png

image.thumb.png.380b07e1cbdf1613d47123ffccb00f6a.png

 

unit AdvAlertWindowReg;   // RUN-TIME definition
{$I TMSDEFS.INC}
interface
uses
  Classes, AdvAlertWindow;
procedure Register;
implementation
procedure Register;
begin
  RegisterComponents('TMS', [TAdvAlertWindow]);  // <---- ONLY THIS
end;
unit AdvAlertWindowRegDE; // DESING-TIME defintions
interface
uses
  Classes, AdvAlertWindow, SysUtils, DesignIntf, DesignEditors, AdvStyles,  AdvStyleIF, Controls, Forms;
type
  TAdvAlertWindowEditor = class(TDefaultEditor)
  protected
    procedure EditProperty(const Prop: IProperty; var Continue:Boolean); override;
  public
    function GetVerb(Index: Integer):string; override;
    function GetVerbCount: Integer; override;
    procedure ExecuteVerb(Index: Integer); override;
  end;
procedure Register;
implementation
procedure Register;
begin
  RegisterComponentEditor(TAdvAlertWindow,TAdvAlertWindowEditor);
end;

.... more implementation code here ....

 

DevExpress (www.devexpress.com) another old friend known to Delphi users, adopts the practical approach used by Borland gurus, that is, their component / class packages are divided between Design-Time and Run-Time, that is, at the time of compiling the suite , you will do the same work as "Build", however, you will see that there are specific packages for Desing-Time, and another for Run-Time!

 

In the end, common sense is worth it and what is most comfortable for everyone!

 

The important thing is that internally, your projects are well designed to facilitate future maintenance, and to avoid "bugs"!

 

As you can see, it is just a matter of what is the best approach for the developer of the components / classes!

 

In the end, the result must be the same! A code that is safe, efficient, and that fulfills what it promises to the target programmer.

 

hug

Edited by Guest

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×