why not deploy it as Runtime package + designtime package?
Posted: Thu Aug 08, 2013 11:58 am
Hi,
I have just upgrade my sources to the latest version and I discovered that TRichView is still deployed just as a Design time only packages.
Is there any good reason for not following the Delphi-correct way of doing components (I.E.: splitting the runtime code and the designtime code in two separate packages? (like I did in the two sources at the end of this post?)
I am asking this because deploying everithing as a single designtime - only package forces the programmer to statically link the TRichview units in ANY binary that uses it, and this leads to many problems:
1) if you are deploying a suite made of many programs, it is sub-optimal to be forced to statically link the same library in every executable
2) My application is so big that I am actually FORCED to split in several runtime packages to be loaded on demand. It loads on demand the package containing the form I have to open.
Ok: if two of the packages need to use TRichView I am forced to statically link TRichView in both packages... but this will make totally impossible for the delphi runtime to load both the packages using TRichView, because they both will phisically contain the same unit and the delphi runtime raises an exception if you try to load a package that contains a unit whose name is the same of another unit already in memory.
This is the biggest issue.
3) a "quick and dirty" solution of the former problem would be to simply change the package definition of TRichView to be a "designtime+runtime" package, so I could link as a package in my application, but here we would have 2 major problems to face:
- such a monolithic package will require to designide.bpl package, which is an actual part of the delphi IDE and can't be deployed. So the delphi license will deny me the right of deploying my program, even If i was able to build it.
- even if I wanna act dirty and deploy my application with designide.bpl, since the delphi ide is a 32 bit application and designide.bpl is just a part of such application, there isn't any 64 bit version of designide.bpl, so I will never be able to build TRichView as a 64 bit package. This means that I would be never able to build a 64 bit version of my application that loads TRichView as a 64 bit package.
- If I deploy such monolithic package with my application, If someone of my customers has delphi xe4, he will be able to install such package in delphi and have a free TRichView component in his delphi toolbar.
Well, maybe I have been a bit too wordy, but the correct way of deploying components for delphi (to avoid all the above problems) is to move all design editors and all calls to RegisterComponents inside a separate "Desing ONLY" package, and make the main package a runtime-only package that:
1) does not have any dependance on design time packages of delphi (DesignIDE and the like)
2) can be built even with the 64 bit compiler
3) can be freely redistributed because it can't be installed in any ide and does not contain any editor that will make the components usable for other developers receiving the package
4) can be used by multiple packages loaded by the same application.
Here is whay I just had to do for the recent sources:
Could you please consider following this standard for the next release?
Thank you!
Carlo Sirna.
P.S.: TRichView is an amazing component.
--- RUNTIME ---
package RVPkgDXE4;
{$R *.res}
{$R 'rvregcool.dcr'}
{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
.... blablabla...
{$DESCRIPTION 'TRichView for Delphi XE4 - REDISTRIBUTABLE RUNTIME PACKAGE'}
{$RUNONLY} // < THIS PACKAGE IS NOT TO BE INSTALLED IN DELPHI
{$IMPLICITBUILD OFF}
requires // << NOTICE THAT THIS DOESN'T REQUIRE DESIGNIDE: this package CAN be 64bit built.
rtl,
vcl,
vclimg;
contains
CRVData in 'CRVData.pas',
CRVFData in 'CRVFData.pas',
CRVPP in 'CRVPP.pas',
CtrlImg in 'CtrlImg.pas',
DLines in 'DLines.pas',
PtblRV in 'PtblRV.pas',
PtRVData in 'PtRVData.pas',
RichView in 'RichView.pas',
RVAnimate in 'RVAnimate.pas',
RVBack in 'RVBack.pas',
RVClasses in 'RVClasses.pas',
RVCodePages in 'RVCodePages.pas',
RVCtrlData in 'RVCtrlData.pas',
RVDataList in 'RVDataList.pas',
RVDocParams in 'RVDocParams.pas',
RVDragDrop in 'RVDragDrop.pas',
RVEdit in 'RVEdit.pas',
RVERVData in 'RVERVData.pas',
RVFMisc in 'RVFMisc.pas',
RVFuncs in 'RVFuncs.pas',
RVGetText in 'RVGetText.pas',
RVGetTextW in 'RVGetTextW.pas',
RVGifAnimate2007 in 'RVGifAnimate2007.pas',
RVItem in 'RVItem.pas',
RVLabelItem in 'RVLabelItem.pas',
RVLinear in 'RVLinear.pas',
RVMapWht in 'RVMapWht.pas',
RVMarker in 'RVMarker.pas',
RVMisc in 'RVMisc.pas',
RVNote in 'RVNote.pas',
RVOfficeCnv in 'RVOfficeCnv.pas',
RVPopup in 'RVPopup.pas',
RVPP in 'RVPP.pas',
RVReport in 'RVReport.pas',
RVResize in 'RVResize.pas',
RVRTF in 'RVRTF.pas',
RVRTFErr in 'RVRTFErr.pas',
RVRTFProps in 'RVRTFProps.pas',
RVRVData in 'RVRVData.pas',
RVScroll in 'RVScroll.pas',
RVSeqItem in 'RVSeqItem.pas',
RVSer in 'RVSer.pas',
RVStr in 'RVStr.pas',
RVStyle in 'RVStyle.pas',
RVSubData in 'RVSubData.pas',
RVTable in 'RVTable.pas',
RVThread in 'RVThread.pas',
RVTInplace in 'RVTInplace.pas',
RVTypes in 'RVTypes.pas',
RVUndo in 'RVUndo.pas',
RVUni in 'RVUni.pas',
RVWordPaint in 'RVWordPaint.pas',
RVXPTheme in 'RVXPTheme.pas',
RVWinGrIn in 'RVWinGrIn.pas',
RVGrIn in 'RVGrIn.pas',
RVZip in 'RVZip.pas';
end.
---- designtime package ---
package RVPkgDXE4Design;
{$R *.res}
{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
{$ALIGN 8}
{$ASSERTIONS ON}
{$BOOLEVAL OFF}
{$DEBUGINFO ON}
{$EXTENDEDSYNTAX ON}
{$IMPORTEDDATA ON}
{$IOCHECKS ON}
{$LOCALSYMBOLS ON}
{$LONGSTRINGS ON}
{$OPENSTRINGS ON}
{$OPTIMIZATION OFF}
{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
{$REFERENCEINFO ON}
{$SAFEDIVIDE OFF}
{$STACKFRAMES ON}
{$TYPEDADDRESS OFF}
{$VARSTRINGCHECKS ON}
{$WRITEABLECONST OFF}
{$MINENUMSIZE 1}
{$IMAGEBASE $400000}
{$DEFINE DEBUG}
{$ENDIF IMPLICITBUILDING}
{$DESCRIPTION 'TRichView for Delphi XE4 - Design'}
{$DESIGNONLY}
{$IMPLICITBUILD OFF}
requires
RVPkgDXE4,
designide,
vcl;
contains
RVSEdit in 'RVSEdit.pas',
RVDsgnSplash in 'RVDsgnSplash.pas',
RVReg in 'RVReg.pas',
RVDsgn in 'RVDsgn.pas' {frmRVDesign};
end.
----
I have just upgrade my sources to the latest version and I discovered that TRichView is still deployed just as a Design time only packages.
Is there any good reason for not following the Delphi-correct way of doing components (I.E.: splitting the runtime code and the designtime code in two separate packages? (like I did in the two sources at the end of this post?)
I am asking this because deploying everithing as a single designtime - only package forces the programmer to statically link the TRichview units in ANY binary that uses it, and this leads to many problems:
1) if you are deploying a suite made of many programs, it is sub-optimal to be forced to statically link the same library in every executable
2) My application is so big that I am actually FORCED to split in several runtime packages to be loaded on demand. It loads on demand the package containing the form I have to open.
Ok: if two of the packages need to use TRichView I am forced to statically link TRichView in both packages... but this will make totally impossible for the delphi runtime to load both the packages using TRichView, because they both will phisically contain the same unit and the delphi runtime raises an exception if you try to load a package that contains a unit whose name is the same of another unit already in memory.
This is the biggest issue.
3) a "quick and dirty" solution of the former problem would be to simply change the package definition of TRichView to be a "designtime+runtime" package, so I could link as a package in my application, but here we would have 2 major problems to face:
- such a monolithic package will require to designide.bpl package, which is an actual part of the delphi IDE and can't be deployed. So the delphi license will deny me the right of deploying my program, even If i was able to build it.
- even if I wanna act dirty and deploy my application with designide.bpl, since the delphi ide is a 32 bit application and designide.bpl is just a part of such application, there isn't any 64 bit version of designide.bpl, so I will never be able to build TRichView as a 64 bit package. This means that I would be never able to build a 64 bit version of my application that loads TRichView as a 64 bit package.
- If I deploy such monolithic package with my application, If someone of my customers has delphi xe4, he will be able to install such package in delphi and have a free TRichView component in his delphi toolbar.
Well, maybe I have been a bit too wordy, but the correct way of deploying components for delphi (to avoid all the above problems) is to move all design editors and all calls to RegisterComponents inside a separate "Desing ONLY" package, and make the main package a runtime-only package that:
1) does not have any dependance on design time packages of delphi (DesignIDE and the like)
2) can be built even with the 64 bit compiler
3) can be freely redistributed because it can't be installed in any ide and does not contain any editor that will make the components usable for other developers receiving the package
4) can be used by multiple packages loaded by the same application.
Here is whay I just had to do for the recent sources:
Could you please consider following this standard for the next release?
Thank you!
Carlo Sirna.
P.S.: TRichView is an amazing component.
--- RUNTIME ---
package RVPkgDXE4;
{$R *.res}
{$R 'rvregcool.dcr'}
{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
.... blablabla...
{$DESCRIPTION 'TRichView for Delphi XE4 - REDISTRIBUTABLE RUNTIME PACKAGE'}
{$RUNONLY} // < THIS PACKAGE IS NOT TO BE INSTALLED IN DELPHI
{$IMPLICITBUILD OFF}
requires // << NOTICE THAT THIS DOESN'T REQUIRE DESIGNIDE: this package CAN be 64bit built.
rtl,
vcl,
vclimg;
contains
CRVData in 'CRVData.pas',
CRVFData in 'CRVFData.pas',
CRVPP in 'CRVPP.pas',
CtrlImg in 'CtrlImg.pas',
DLines in 'DLines.pas',
PtblRV in 'PtblRV.pas',
PtRVData in 'PtRVData.pas',
RichView in 'RichView.pas',
RVAnimate in 'RVAnimate.pas',
RVBack in 'RVBack.pas',
RVClasses in 'RVClasses.pas',
RVCodePages in 'RVCodePages.pas',
RVCtrlData in 'RVCtrlData.pas',
RVDataList in 'RVDataList.pas',
RVDocParams in 'RVDocParams.pas',
RVDragDrop in 'RVDragDrop.pas',
RVEdit in 'RVEdit.pas',
RVERVData in 'RVERVData.pas',
RVFMisc in 'RVFMisc.pas',
RVFuncs in 'RVFuncs.pas',
RVGetText in 'RVGetText.pas',
RVGetTextW in 'RVGetTextW.pas',
RVGifAnimate2007 in 'RVGifAnimate2007.pas',
RVItem in 'RVItem.pas',
RVLabelItem in 'RVLabelItem.pas',
RVLinear in 'RVLinear.pas',
RVMapWht in 'RVMapWht.pas',
RVMarker in 'RVMarker.pas',
RVMisc in 'RVMisc.pas',
RVNote in 'RVNote.pas',
RVOfficeCnv in 'RVOfficeCnv.pas',
RVPopup in 'RVPopup.pas',
RVPP in 'RVPP.pas',
RVReport in 'RVReport.pas',
RVResize in 'RVResize.pas',
RVRTF in 'RVRTF.pas',
RVRTFErr in 'RVRTFErr.pas',
RVRTFProps in 'RVRTFProps.pas',
RVRVData in 'RVRVData.pas',
RVScroll in 'RVScroll.pas',
RVSeqItem in 'RVSeqItem.pas',
RVSer in 'RVSer.pas',
RVStr in 'RVStr.pas',
RVStyle in 'RVStyle.pas',
RVSubData in 'RVSubData.pas',
RVTable in 'RVTable.pas',
RVThread in 'RVThread.pas',
RVTInplace in 'RVTInplace.pas',
RVTypes in 'RVTypes.pas',
RVUndo in 'RVUndo.pas',
RVUni in 'RVUni.pas',
RVWordPaint in 'RVWordPaint.pas',
RVXPTheme in 'RVXPTheme.pas',
RVWinGrIn in 'RVWinGrIn.pas',
RVGrIn in 'RVGrIn.pas',
RVZip in 'RVZip.pas';
end.
---- designtime package ---
package RVPkgDXE4Design;
{$R *.res}
{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
{$ALIGN 8}
{$ASSERTIONS ON}
{$BOOLEVAL OFF}
{$DEBUGINFO ON}
{$EXTENDEDSYNTAX ON}
{$IMPORTEDDATA ON}
{$IOCHECKS ON}
{$LOCALSYMBOLS ON}
{$LONGSTRINGS ON}
{$OPENSTRINGS ON}
{$OPTIMIZATION OFF}
{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
{$REFERENCEINFO ON}
{$SAFEDIVIDE OFF}
{$STACKFRAMES ON}
{$TYPEDADDRESS OFF}
{$VARSTRINGCHECKS ON}
{$WRITEABLECONST OFF}
{$MINENUMSIZE 1}
{$IMAGEBASE $400000}
{$DEFINE DEBUG}
{$ENDIF IMPLICITBUILDING}
{$DESCRIPTION 'TRichView for Delphi XE4 - Design'}
{$DESIGNONLY}
{$IMPLICITBUILD OFF}
requires
RVPkgDXE4,
designide,
vcl;
contains
RVSEdit in 'RVSEdit.pas',
RVDsgnSplash in 'RVDsgnSplash.pas',
RVReg in 'RVReg.pas',
RVDsgn in 'RVDsgn.pas' {frmRVDesign};
end.
----