I created a package with components ( a runtime package, and a design package) in delphi 10.1 Berlin.
I want to use components of this package in a vcl project.
I want the code of the components being embedded in the project. (I don’t want to link the project to an extern bpl)
Each time I compile the project, Delphi tells that sources of the components are not found.
I could add the directory of the components sources in the path of the project, but I don’t want do that.
Since the code of the component is in the bpl, I guess there must be a solution for Delphi to "bind" the bpl to the project without knowing where are the .pas or the .dcu of the components, but I can’t figure how to do that. Is it possible ? how ?
As I read what you have written, it seems that you do not actually want to use packages in your executable. That is what I infer from this statement:
I don’t want to link the project to an extern bpl.
So you need to link the source code into the project. There are a variety of ways:
Include the source files (.pas and any auxiliary files) in the executable project.
Add to the project search path the directories containing the source files.
Add to the project search path the directory containing the compiled .dcu files.
Which you choose to do is entirely up to you.
Note that you should also make sure that the Use runtime packages project option is not checked for your executable project.
Now, I appreciate that in the question you state that you don't want to do what I am advising you to do. Rather you would prefer to somehow embed the package into the executable. But that's not what how packages are designed. If you wish to include everything in the executable then you do just that.
Delphi needs to know where the source files (.pas or .dcu) of your component are.
You must add the source folder to the library path (found under Tools - Options - Delphi Options - Library)
Related
I'm trying to use a static library in my C++ Builder project. The lib is created by using DCC32 to compile Delphi source code with -JL option. My Delphi source code is design as a "Designtime and runtime" package, which mean s all the code is built into one package. I want to know how can I use this static library in our C++ Builder project? Thanks in advance.
As David said, the Delphi compiler can't create static lib files at all. What you are trying to link to is an import library for a designtime/runtime package.
Delphi (and C++Builder) packages are not static libs, they are DLLs with a lot of extra information onboard, which makes it easy for Delphi and C++Builder code to link to them and the types inside. They are more or less equivalent to C# assemblies (guess where the C# people got the idea ;-).
To use such a package, in case you really want to use them, select the "build with packages" option from the project options and select this package too.
But if you want to create a single, standalone application, you don't build with packages and the Pascal files get linked into your application as if they came from a static library. But instead of specifying one lib file, you simply specify the .pas files in the project manager, i.e. you simply add the bunch of .pas (or .obj) files to your application directly.
The project will take care of compiling the Pascal files and linking them to your application.
Note that to install components into the IDE, you need a design time package (and that might link to a runtime package). But you don't need packages for your application.
These are some steps for your consideration:
Use -JP to generate obj files
Add these obj files in link step into your ilink32 command
If you use IDE and do not which ilink32 params then you may consider procexp or procmon to see these params.
I have a BPL project (with some base stuff) and an EXE project which has in it's Search Path the location of the other project's output (BPL and DCP). When the EXE project is built with "Build With Runtime Packages", it builds fine. However, it requires me to deploy the EXE and the BPL. So far so good.
Since I'd rather deploy just the EXE (no matter it gets bigger), I'd guess that I'd just uncheck "Build With Runtime Packages" and that'd be it, but it's not the case. It won't build, and start complaining about the missing classes. The only way I can compile the EXE project is if I add the path to the actual BPL project's DCUs to the EXE project's Search Path. I can do that, but why am I forced to point to the DCUs? Can't Delphi just take them from the BPL? It's not just a matter of taste, if I go this way, and link to the DCU's, when it comes to DCUs belonging to forms, it will then ask me for the forms DFMs, forcing me to also include my sources folder to the EXE project's Search Path, and now it would seem as they are getting compiled, which is prohibitive. I can't recompile my BPL project codebase each time I want to compile my EXE project.
I hope I have made myself clear.
Any help on how to achieve what is asked in the title is appreciated.
Thank you.
There are two ways to link external libraries: static and dynamic.
When you are using runtime packages, this is a dynamic linking. Actual implementation is in the BPL file (which is a simple dll actually), methods and classes are imported from it on the process start. This reduces exe size, but requires BPL file to be shipped (same as usual dll). DCU files are not needed, because everything is already compiled and linked, linker need only to create import section.
When runtime packages are disabled, linker has to take object files for all classes and methods and combine it into the one executable. It could not extract this data from the BPL, because its is already linked executable. It would have to unlink it first, separating different modules implementation, which is basically impossible. So you have to provide DCU files, containing compiled object code to link your program.
So answer for your question title is simple - no it is not possible.
No, you can't. If you want to use runtime packages you have to turn on the compiler option to build with runtime packages.
As to the second part of your question:
Building with runtime packages uses the *.dcp files to compile (the .dfm streams are linked into packages' resources so the *.dfm files are not needed directly).
Building without runtime packages needs the *.dcu and *.dfm files (and any other required files).
In either case, you need to have the required files in your library/search path to be able to compile/build.
It is possible, but is very hard to implement.
And you will need to create a third project for this purpose - a loader.
You need to turn your original EXE project to a DLL built with runtime pckages.
The loader can include your DLL project, rtl.bpl, vlc.bpl and your BPL project as resources inside loader executable.
Loader will need to manually do all things that are done by LoadLibrary Windows API.
You can read more about how to load DLLs from memory and find some code samples to start with here.
Which folders should I put in the library path in the Delphi IDE ? Only the ones containing .dcu ? I had problems when I updated some libraries.
EDIT
What I want to achieve is to avoid the error F2051 Unit xxxxx was compiled with a different version of yyyyy when I update libraries.
As a general rule:
The Library Path setting in the IDE should contain paths referenced by all/most or many of your projects. This will almost certainly include the paths to source of any package libraries installed in the IDE (that is, components installed into your IDE component library).
Any libraries that are used only by certain projects should be included in the Search Path setting for those specific projects.
You should only need to include the path to any dcu's for libraries for which you do not have the source. But whether you add the path to the IDE or to a project settings is independent of whether that path is to source or dcu files.
As noted right at the start however, this is only a very general rule of thumb. Your specific needs may be different in a way that is not possible to determine from the question in its current very general form.
I want to create *.bpl file but I am failing to do so.
Specifically, I am trying to make JEDI plugins, but I have tried an empty pure Delphi package, too.
If I create a new package in Delphi XE3, I get an empty unit - if I "make" this project called "Package1.bpl", I get a .dcu file in "debug/win32/", but no .bpl file.
No error is reported by the compiler.
An empty JEDI plugin (bpl-style) only gives a .dcu, too, while an empty dll-style JEDI plugin gives a .cdu and a .dll file in "debug/win32/".
This is the first time I am trying to make a new package, so I am completely lost.
What am I missing?
Go to the Tools menu and navigate to Environment Options -> Delphi Options -> Library.
There you find the Package Output Directory and the DCP Output Directory. These directories are the default output directories for BPLs and DCPs, so the bpl will be created if your packages is compiled, but in a different directory from what you expect.
The JEDI plugins probably have their output directory configured otherwise in Project -> Options.
For those that don't want to travel into Delphi IDE/options etc, lately in Delphi XE it's something like this:
"C:\Users\Public\Documents\Embarcadero\Studio\17.0\Bpl;"
Your exact folder might be different based on 17.0
These folders also end up in the path environment variable of your system, bit dangerous and can lead to some mighty magic loading confusion ?!
"How's that BPL still loading after it was deleted from my local project folder ?" :)
Another solution is to add "." to your project settings without the "". Prevents you from having to modify your delphi environment options/settings, something you probably never want to do since JEDI and other projects may rely on these default settings to function properly. Only change it if you know what you are doing and how to correctly make JEDI and others work if it was changed, this may get tricky/hairy, probably requires search paths to be added.
How to set "Directories/Conditionals" in Project Options and "Library" path in Environment Options? Delphi help don't say much about these very important settings. I have all kind of strange errors because of wrong dependencies between my VCLs.
1.
I have merged a large set of 3rd party controls in a package called ThirdPartyPackages_D7.dpk. This is useful when I reinstall Delphi because I don't have to reinstall all those 3rd party VCLs amnually.
Then, I have my own controls in MyControls_D7.dpk which depends on the ThirdPartyPackages VCL. I also have another package BlgPackage.dpk that depends on MyControls.
At the end of the chain is my application (DPR project) which is using the controls in BlgPackage.
ThirdPartyPackages.dpk -> MyControls.dpk -> BlgPackage.dpk -> MyApplication.dpr
When I change/edit something to the second package (MyControls.dpk) and build the DPR application, it works. The compiler sees the changes made into that package.
However, if I close the project and load and compile the BlgPackage, it throws a nasty message that function xyz cannot be found in MyControls because I delete it (I have loaded MyControls' units into IDE in parallel with application's units). It seems that building the application only refreshes the DCU files for all used packages but not the DCP/BLP files.
How do I write and compile the code in the packages without explicitly loading the packages into the IDE and building them?
(Note: I have a nasty bug that does not allow me to switch between projects without restarting the IDE or to load a group of projects/packages (*.bpg) at the same time.)
2.
Another problem is that I want to store the compiled files (DCP/BPL/DCU) of a package in its folder (for example c:\MyProjects\Blg).
If I set the "Output directory", "Unit output directory" and "DCP output directory" boxes of BlgPackage package to its folder, not only its BPL/DCU/DCP files will be stored there but also the BPL/DCP files of MyControls will be stored there.
How can I have the binary files of each package in a separate folder?
Delphi 7, Win XP, all projects set to "Rebuild as needed"
You should explicitely compile packages - just compiling package files is not enough and as you have noticed leads to problems.
In modern Delphi versions you can create a project group (not sure about Delphi 7) that contains an application and packages you want to develop with the application, and you can easily switch between them and complile packages without need to close/reopen the application.
BlgPackage should not have an access to MyControls package sources (through "Library" path or by using the same directory), it should access only already compiled MyControls package, else the files from MyControls are compiled every time you build BlgPackage and the compiled files are stored in BlgControls DCU directory
ADDED
The "Library" path should lead to compiled files (.dcp, .dcu) and (if needed) resource files (.res, .dfm) only - it is enough to compile applications and packages that requires "MyControls" package. You can set the directory for compiled files directly in the package settings, and you should copy the resource files (if you need them) to the same directory manually. This directory should be included into "Library" path, or else you can use a directory already contained in "Library" path.
The "Library" path should not lead to source files (.pas) if you don't want these files to be compiled every time you build your BlgPackage or an application that requires "MyControls" package.
I use much simpler way for 3rd partie components and reinstalling Delphi.
Open regedit and find
[HKEY_LOCAL_MACHINE/SOFTWARE/Borland/Delphi/xxx] where xxx is version and export whole
branch.
Open file and delete keys LMKEY, LMLIC.
Copy C:\Program Files\Borland\Delphi x\Projects\Bpl folder to another location
Copy C:\Program Files\Borland\Delphi x\Imports to another location
Reinstall Delphi including any updates and GExpert
Import previously saved registries
Restore Bpl And Imports Folder
And whoala, Delphi is back with all 3rd partie components and IDE settings. Only limitation is that all components must reside in same folder before and after reinstalling Delphi.
This also restores TeamSource settings. If you are reinstalling Windows as well, be sure to make windows user with same user name as before.
MY solution (kinda dirty, but hey it works):
I put ALL 3rd party libraries.controls in a single package (a super-package). I put all my controls in a single package.
Now, when I migrate the packages to a different PC all I have to do is to copy/paste two folders and set two paths.
Works for me - others may not agree with it and I can't blame them. I blame the 'hell designers' from Borland/Embarcadero. If you look on StackOverflow you will see that until now nobody provided an elegant solution to this.