Can I make the `requires` clause in a package conditional? - delphi

I'm using Anders Melander's DragDrop package.
It works fine in Win32 mode, but needs adjustment for 64 bit.
I do this by adding {$IFNDEF CPUX64} to comment out the references to the designIDE.
However when I change the package source from
requires
rtl,
DesignIDE;
to
requires
rtl
{$IFNDEF CPUX64} ,DesignIDE{$ENDIF};
The compiler simply throws away the DesignIDE line in the package source, leaving only:
requires
rtl;
Which works fine for X64, but breaks as soon as I rebuilt for 32-bit.
Is there a way to have one package including design-time items for win32 with the conflicting items IFDEF'ed out for X64? Or am I forced to create a separate Runtime package for X64?

No, you cannot use conditionals in any project main file. The IDE owns and controls it, and is subject to discarding (and even destroying) any customization you do with conditionals. You will need to create a second package for this, which is normal practice for using DesignIDE anyway. Even if it weren't for supporting 64bit, you're not permitted to deploy DesignIDE with any application. It is for the sole purpose of integrating with the IDE, which for legal reasons, must only reside in a Design-Time package.
Bear in mind also that the Design-Time package must only be Win32, as the Delphi IDE is only 32bit. Then, the Run-Time package can be any supported platform you wish (i.e. Win64), of course as long as it's supported by any framework it might be using.

Related

How to include Vcl.ImgList in Delphi

In compiling a Delphi 2007 project, I receive the following error:
E203: Undeclared identifier: TChangeLink
This appears to belong to the Vcl > ImgList library.
My limited understanding is that Vcl is part of the native Delphi libraries. How do I verify that it is correctly referenced?
It's because ImgList isn't in your uses clause. Based on information you provided in a comment,
uses contains this line:
Clipbrd{$IFDEF DELPHI4}, ImgList {$ENDIF}, dxCommon{$IFDEF DELPHI6}, Variants{$ENDIF}
It's because the {$IFDEF DELPHI4} is excluding it, presumably because DELPHI4 isn't defined. This is typically caused by using code that is in open-source or commercial component sets that use those version defines to support multiple Delphi versions with the same source. (This is usually done in a .INC file of some sort; Jedi uses JEDI.INC, for instance, for all of the version defines for various compiler and IDE related differences.)
The best solution (to maintain cross-version compatibility) would be to update the definitions to include Delphi 2007, but I can't offer advice on how to do so because I don't know where the define is located. The other alternative is to just remove the {$IFDEF DELPHI4} from the uses clause, if you don't need to worry about earlier versions of the IDE/compiler.

Recompile modified VCL unit

I have to compile my project with a changed VCL unit. I use Delphi XE8. I copied Vcl.StdCtrls.pas from D:\Program Files (x86)\Embarcadero\Studio\16.0\source\vcl to my project folder where my .dpr file is localed, then I changed my copy of Vcl.StdCtrls.pas. I also added this unit to project tree. The problem is that with Delphi XE8 such method of recompiling VCL units no longer works. I put an obvious syntax error in my modified Vcl.StdCtrls.pas unit. Compiler does not report the error which means it does no even check the file. I always do a full build Shift+F9. I found a similar question How to recompile a specific unit from the VCL? but like I said, it no longer works, not for Delphi XE8.
Also, the modified unit is on my uses list in .dpr file:
uses
Vcl.StdCtrls in 'D:\Dev\MYPROJECT\Vcl.StdCtrls.pas',
...
// it does not help
This seems to be a bug. I guess you're using runtime packages. In XE7 such project will not compile - which is the correct behavior. In XE8 it compiles, apparently using the VCL runtime package and ignoring your modified unit.
Edit:
Note that even in previous Delphi versions, modifying a VCL unit while using runtime packages would still require you to repackage the modified packages and their dependencies (in this case, vcl and rtl).
In other words, you cannot simply use a modified unit while linking against a runtime package which contains another copy of that unit. Unit names must be unique within the full scope of the project, including the main executable and all linked runtime packages.
So the solution for you is to either:
not use runtime packages, or
repackage all required units into your own runtime packages, and link against them instead of Embarcadero-supplied rtl, vcl etc.

How to build delphi projects for WIN64 when units inside it uses DesignEditors DesignIntf?

I am trying to migrate some code from Delphi 5 to Delphi XE7-WIN64. The scenario is DesignEditors is 32bit only since the IDE is 32 bit application. And the project I am migrating has units which have uses clause containing DesignEditors or DesignIntf or both.
Putting -LUDesignIDE in Build Configurations>Edit>Delphi Compiler>Compiling>Additional options to pass to compiler>-LUDesignIDE
Gives the following as first error on build
[dcc64 Fatal Error] E2202 Required package 'DesignIDE' not found
I am using Delphi XE7 trial version.
It sounds like you have a package which is both design-time and run-time combined into one. In most scenarios however, you must split your package into two different packages. One package is run-time (where you implement all of your actual library), and the other is design-time (which exposes your library to the IDE).
That being said, the design-time packages must work directly with the Delphi IDE. The Delphi IDE is 32bit, so the design-time package must also be 32bit. Whereas, your run-time package will support whatever platforms are needed. Your design-time package is only responsible for registering your components, property editors, etc. to the IDE.
Anything which has anything to do with the IDE (such as registering components, registering property editors, etc.) Must be in your design-time package which is only 32bit. Because of legal copyright issues, all design-time implementation must be in a design-time package, separate from your run-time package.
Start by creating a new design-time only package, same name but prefixed with DCL. Then, change your original package to run-time only. Create a new unit now in your new design-time only package. This unit will be dedicated to registering all IDE design-time interaction. Everything in your run-time package which relies on these design-time units must be converted over to this design-time package. These units which you cannot find are only compatible with the 32bit Delphi IDE.
The new design-time only package will then have to require your run-time package. You'll have to compile the run-time package first before you can compile the design-time package. Any time, you make changes to your library, you need to 1) re-compile the run-time package, 2) re-compile the design-time package, and 3) re-install the design-time package.
The ToolsAPI units can be included in Win32 designtime packages, and nowhere else. You are trying to include them in a Win64 executable project. That is not allowed.
The solution is that you remove all the ToolsAPI units from your project.

Package (BPL) Automatic Naming Suffix

I write a lot of components and libraries for Delphi, most of which require the use of BPL Packaging so that they may be installed into the IDE.
This is simple enough and works well, right up until you want to maintain a single set of Package Project Files (in a single Project Group), but also want to compile and distribute those same packages for different Delphi versions.
Up to now I've been creating a different Package Project for each version of Delphi, and explicitly defining a Delphi Version Identifier as a suffix (e.g. Kinect_XE.bpl and Kinect_XE2.bpl).
I am aware that, in the Project Options for a Package Project, under Description, there are the fields LIB prefix and (more importantly for my needs) LIB suffix.
I am further aware that if I place a value in LIB suffix, it'll be appended to the end of the compiled BPL's filename.
My question, however, is first whether it is possible to have the IDE automatically populate the LIB suffix field with the IDE/RTL Version number, and if so... how?
I'm fairly certain this is possible, as it would appear that vcl120.bpl (and its counterparts for each respective version of Delphi) can be Referenced (as requirements) of your own packages using just vcl rather than having to type the full vcl120. It is, in fact, this same behaviour I'm hoping to achieve... where my packages can intra-reference eachother (as neccessary) without having to provide version-specific references to accommodate the suffixes.
Equally important is that resolving this will enable me to maintain a single set of Project Files in a single Project Group (with the obvious exception of XE2 where its Project Files don't necessarily behave very well with previous versions of Delphi due to the Platforms addition).
I suspect that I may need to put a value like $(VER) (or something similar) in the LIB suffix field, but this appears not to work and I've scoured Google looking for the correct solution.
Hope you can help!
UPDATE 1
I am now writing an IDE plugin to be used with (in the very least) Delphi 2007 to XE2, which gives DLL and BPL projects a new option called AutoSuffix. When toggled On, any IDE with the AutoSuffix plugin installed will immediately apply the correct IDE version suffix to the project.
The AutoSuffix plugin will be made available (freely) for everyone within the next 24 hours, and this question updated accordingly.
UPDATE 2
Okay... Delphi 2007 is being a pain! I've made AutoSuffix work with 2009 to XE2, so far, but 2007 requires a little more time (patience appreciated).
UPDATE 3
It would appear as though Embarcadero have heard our collective cry for simplier package unification between versions.
Mark is going to push this through to see if future versions of Delphi can accommodate a {$LIBSUFFIX AUTO} feature. I hope to hear back very soon whether this will be the case. If so, it certainly affects the way AutoSuffix will need to work on XE2 and older versions (as presently it doesn't provide the simple AUTO switch.. it has its own method).
My hope now is that EMB will take this request seriously, provide it as an integral feature going forward, so that it becomes a simple case of using AutoSuffix on existing versions to unify the process accross all versions!
AFAIK for Delphi up to XE2 there is no automatism for doing this.
Concerning the requires clause: when you require another package you are actually using the dcp, which doesn't inherit the LIBSUFFIX. Thus it is sufficient to require VCL.dcp during compile time, while VCL160.bpl is actually used during runtime. The DCP includes the complete BPL name to resolve that.
This makes the LIBSUFFIX approach superior to the simple "rename the package for each version of Delphi" one.
A solution like that suggested in QC83229 would make it easier to port a package to a newer Delphi version, but then you are still stuck with dproj files that are not backwards compatible.
I normally use different folders for each Delphi version, where only the project files are stored. For a new Delphi version I only have to copy a folder and change the LIBSUFFIX.
LIBSUFFIX directive is in *.dpk file, and you can edit *.dpk file manually.
You can write, for example
{$IFDEF CONDITIONALEXPRESSIONS}
{$IF CompilerVersion = 20.0}
{$LIBSUFFIX '120'}
{$IFEND}
{$IF CompilerVersion = 21.0}
{$LIBSUFFIX '140'}
{$IFEND}
{$ENDIF}
The bad thing is that IDE does not respect your manual edits of *.dpk file and deletes them then you make changes in a package. That is why some component vendors that use conditional defines in *.dpk file say in installation instruction if asked to save changes say 'NO'.
My suggestion would be to add this as a configurable option to project option sets (see QC #86491.) Rather than updating all the packages it would be sufficient to update a single option set file.
In fact, it seems the DllSuffix tag is recognized by the option set files in Delphi XE/XE2. Adding <DllSuffix>160</DllSuffix> to the <PropertyGroup> section of an option set file will cause the suffix to be appended to the package in the project manager. However, you still have to open the project options and click OK in order for it to be saved to the .dpk file.
I agree that it would be extremely useful with this feature (I would think also for the packages in the RTL.)
{$LIBSUFFIX AUTO} feature was added in Delphi 10.4.1:
In previous versions (version 10.3 and earlier) of C++Builder and
Delphi developers building packages needed to manually set their
package’s library suffix setting. The DocWiki “What’s new in version
10.4.1” mentions a new IDE projects option for setting the library suffix:
“Package AUTO libsuffix: packages can now have an automatic version
suffix, instead of manually updating and specifying the right version
suffix with each new release. (The compiler quietly supported this in
10.4, but full support for the feature in the IDE and package project settings is introduced in 10.4.1.)”

which one is best for use in delphi i.e use of package or dll

I'd like to use a .dll with a delphi application, but I'm curious if a delphi package is more flexible than dll?
You can read this article on my Blog: "DLL's, BPL's Static and dynamic loading, and Packages in Runtime"; Is 's writed in Spanish but you can try the Automatic translation (on right part of the page).
Basically BPL is an extension of a DLL. It's a DLL with some things added.
(POSITIVE) If you use BPL's you can do more things with the DLL. More power. You can use RTTI (you must build your applicaction with runtime package for accesss RTTI).
(NEGATIVE) If you use BPL's with more powerfull, you can only use it with Delphi, no with other languages.
If you're sure that you only use it with Deplhi, I think that you must use BPL. Search samples about RTTI, RegisterClasses, GetClass method, LoadPackage (for dynamic load),...
Regards.
Escuse-me for my poor english. It's not my natural language.
Not knowing excactly what you mean, and believing you are a newbie (so I may omit some specialized aspects), and implying you know what a DLL is:
The first and foremost reason to build a package is authoring a design-time component.
You can do quite everything (well..almost...) that a package does just as well with DLLs -- except for the design-time stuff.
Additionally, you can package multiple compiled packages into one Borland Package Library (BPL file) without having the design-time features in mind. If you think deploying and runtime-binding one BPL is better than various DLLs, go for it. The primary purpose is design-time support, though.
Packages are special DLLs that can export classes, while DLLs can only export functions. Yes, you can write a DLL function that creates and instance of a given class, but you can't use a class declared in a DLL (unless using some hacks maybe), while you can use a class declared in a package directly. Packages "know" about Delphi object architecture, while DLLs don't. On the other end, DLLs can be used from any language able to use them, while packages are Delphi-specific.

Resources