Please help me with this problem.
This problem comes when I move my project to another PC. This program works fine on my PC.
You have your project configured to compile with Runtime Packages enabled. That means for any standard, 3rd party, and custom packages that your project uses, you have to deploy their respective BPL files that your EXE depends on, in addition to the EXE itself.
A BPL is just a fancy DLL with built-in support for Delphi’s RTL and VCL/FMX frameworks. The error you are getting is a standard Windows error popup dialog when the OS loader can’t find a required DLL that an EXE is statically linked to.
To avoid the error, you need to either:
deploy all required BPL file(s) along with your EXE. Use a tool like Dependency Walker to figure out what they are.
turn off the “Runtime Packages” option. Your EXE will be much larger, but it will be more self-contained, as the relevant package code will be built into the EXE itself.
Related
I'm still using Delphi 5.
I have a program which is a rewrite of an earlier program and in fact uses the root unit from the earlier program. When I compile it, Delphi doesn't link the BPLs into the EXE for some reason. New programs and old programs compile fine, so the problem is obviously with this one program. I've compared the project options for Linking and Compiling with other programs which are linking just fine. The compiler options in the main unit are the standard ones.
While the program is on my development box, it runs as expected, obviously reading the BPLs in the development area. But of course it won't run on another machine unless I copy the BPLs over, which is obviously not very clever.
I've read everything I can find on the subject, but although I've found references to linking not working, I haven't found anything which helps to work out why the linking isn't working in just this one case.
Can anyone point me at some documentation about this or point out something I've obviously missed looking at? I know it's something I've done, but despite spending hours on it I can't work out why!
Since there are no errors generated, I can't show you where it went wrong. Any suggestions about where I might find the problem would be much appreciated.
If you go to the Packages tab of your Project Options, is the Build with runtime packages checked?
If it is, you need to deploy the other packages to other machines if they aren't already on those machines at locations where they can be found by the OS.
If it isn't, Delphi will compile and link your project as an .Exe file and the code from the DCUs in the packages will be statically linked into your .Exe so you won't need to deploy the .BPLs (and they would be ignored even if you did).
AFAIK, when Delphi compiles a project to an .Exe (that is, if Build with runtime packages isn't checked), the compiler gets the other units' code to link from the .DCU files, rather than from the .BPL files. If it can't find the .DCU files, or you have told the compiler to do a "Build" it will attempt to generate the .DCUs them from the corresponding .PAS files if it can find them either in the project directory or via the Seach Path under Directories/Conditionals.
Using Embarcadero RAD Studio XE7, I wrote a runtime package containing a VCL component (it's a TGraphic descendent). Now I want to distribute this component, but only the compiled package without his source code. I cannot include it in the distribution because I wrote this package for a company that want to sell it and keep the control on his sources, so distributing the source code isn't an alternative in this case.
The component package depends on 2 other packages I also wrote. All of these packages are runtime, however a graphic filter is registered. After the package is installed, this filter allows me to open a new kind of image file from several native VCL components like TImage on my development computer. This behavior is very important and I want to keep it on the target IDEs.
Ideally I want my package to be installed on all RAD Studio platforms between XE and 10.2 Berlin. However I recently tried to compile my package in release on my devel computer and deploy it manually on another computer installed with RAD Studio XE4. The result was unconvincing:
Trying to install the .bpl file using the Component->Install packages... failed with a "The specified module could not be found" error. When opening the .bpl file with the Dependency Walker tool, I noticed that several dependencies like RTL210.bpl were missing
I also read somewhere that only design time package may be installed this way, it is exact?
Putting all the files (.bpl, .lib, .hpp, ...) of one of my package manually in the XE4 common dirs, I was able to compile a test project successfully. However several functions in my package were unavailable (resulting to an unresolved external when trying to use them)
Although I have several past experience about software and package distribution, I must confess that I have absolutely no idea about how to build a such package for deployment. In all my past scenarios I always distributed the package projects and source codes, and let the user install them on their own IDE.
I searched information about that in the past days but I found nothing. So if somebody can explain how to achieve a such package, or can point me to a document or website describing the process, or eventually give the name of a tool that can do the job, I would be very grateful to him.
Regards
If you don't want to to distribute the source files, you then need to provide the .dcu and bpl files. As Uwe says, you need different packages for each Delphi distribution.
What I have done in the past is to create an installer which builds and registers the packages. You can find the full description here:
http://www.kouraklis.com/2016/10/build-and-install-packages-in-delphi-ide-using-innosetup/
I think you can modify the script to skip the call to MSBuild.
Hope this helps.
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.
I'm trying to make a package for a custom component I made. It's based on several libraries, including Graphics32, GraphicEx and CCR.Exif.
I created a Package project, wrote the unit including its Register procedure, added some extra references Delphi notified me about to the requires section (including dbrtl.dcp, inet.dcp, soaprtl.dcp, vclimg.dcp, xmlrtl.dcp and dclGraphicEx140.dcp) and added many units to the contains section to avoid warnings about it happening implicitly. The project compiles and can be installed and used on my own machine without issues. However, when I want to install it on another machine, the troubles begin. In the end, I had to copy about all DCUs from all 3rd party components I used, plus both the DCP and BPL from GraphicEx, which I had to install even.
Supplying a lot of files is a bummer, yet surmountable, but having to install other packages as well is a no go. I could get rid of that DCP and BPL by putting even more units in the contains section, but that resulted in error messages on my own machine where GraphicEx is actually installed. This is confusing to me, because with Graphics32 nothing like that occurs...
Anyway, how do I keep my distribution to a minimum and avoid such situations? I want other developers on my team to be able to use the package without worrying about what I used to build it. For a start, can't all the 3rd party units be compiled into my own DCU?
What you experienced is an usual thing to the ones who write components. The distribution is always like that. Packages do not carry other packages, insted they reference them. It´s in their nature.
In order to overcome such a situation I always treat my components in the same way I would if they were a product to sell: I build a setup wizard that distributes and registers everything the package needs.
In my case InnoSetup works very well (http://www.jrsoftware.org/isinfo.php).
Summary
Haven't use Delphi for a while, but, did develop my custom visual controls (Last version I work was Delphi 6).
There are 2 issues when dealing with packages dependencies. One is installing at the Delphi enviroment, making controls appear on the component palette, plus, component editors & property editors.
And another when distributing the compiled packages into customers machines.
It also depends, on which version on Delphi you are running.
Design Time
When developing a custom package, there is a tab for package options, that indicates the destination folders.
The manuals usually tell the developers to leave those textboxes empty. That sometimes works, sometimes doesn't. I explicity write each folder path, in the respective textbox.
There is a textbox path for the ".dcp" files, other for the ".dcu", and so on.
If you have visual controls and stuff like property editors or component editors, its better to split the code in 2 packages ("Runtime" & "Designtime").
I usually put the delphi (packages) projects outside the delphi installation folder.
Run Time
Usually, the quick way is to put the "*.bpl" ".dcp" files in the Windows (32) / system folder, or similar "DLL" windows folder.
Packages folder structure source code suggestion
Managing packages can be difficult. I don't know how much the installation process has changed with Embarcadero, and the newer versions of Delphi. The following chart,is an example on how organize the source code. Hope it helps.
[-]--+--c:
.....|
.....+--[-]--+--software
.............|
.............+--[+]-----java
.............|
.............+--[+]-----php
.............|
.............+--[-]--+--delphi (not the delphi folder in program files)
.....................|
.....................+--[+]-----apps (source code for delphi programs)
.....................|
.....................+--[+]-----other
.....................|
.....................+--[-]--+--packages (all delphi packages source code here)
.............................|
.............................+--[+]-----lib (a single package for non visual controls, libraries)
.............................|
.............................+--[+]-----tools (package pair for non visual tcomponent descendants)
.............................|
.............................+--[+]-----json (example)
.............................|
.............................+--[+]-----xml (example)
.............................|
.............................+--[-]--+--mycontrols (folder custom visual controls)
.............................|.......|
.............................|.......+--[-]--+--delphi40 (folder for delphi40 version of "mycontrols")
.............................|.......|.......|
.............................|.......|.......+----------dsgvclctrls40.dpk (design-time package "mycontrols")
.............................|.......|.......|
.............................|.......|.......+----------runvclctrls40.dpk (run-time package "mycontrols")
.............................|.......|.......|
.............................|.......|.......+--[+]--+--demos (individual example for each "mycontrol")
.............................|.......|.......|
.............................|.......|.......+--[+]--+--design ("*.pas" component editors destination folder)
.............................|.......|.......|
.............................|.......|.......+--[+]--+--sources ("*.pas" source code destination folder)
.............................|.......|.......|
.............................|.......|.......+--[+]--+--bin ("*.dcu" destination folder)
.............................|.......|........
.............................|.......+--[+]--+--delphi50 (folder for delphi50 version of "mycontrols")
.............................|.......|........
.............................|.......+--[+]--+--delphi60 (folder for delphi60 version of "mycontrols")
.............................|.......|........
.............................|.......+--[+]--+--delphi70 (folder for delphi70 version of "mycontrols")
.............................|................
.............................+--[-]-----etc...
Cheers.
Thijs, you simply cannot do that with only a package. The target developer will require almost everything you added to the package. But there is an alternate way of doing what you want: Build a DLL with all the components/libraries you are using in your own component and wrap all those external components/libraries into some code you will export from the DLL. Then build your component without using the external components directly but the DLL you've built. You cannot in you component "use" any unit of the other external components/Libraries. You have to build a new unit with all the datatypes and required declaration for anything you export from your DLL. All this is perfectly working but will quickly becomes very complex for a large number of external components or libraries.
I think AlexSC has the best answer, but I think there might be an alternative if you ansolutely must have a custom component that has no dependencies.
I ran into the Delphi dependency frustrations a little while back trying to create an in-house component for our developers. My suggestion:
Uninstall all dependencies your component uses
In your component package, remove the above dcp from the requires section from your package.
Copy the source files of your dependencies to your components
When you distribute the component, you'll have to distibute it with the code of the required dependecies
You'll run into issues if you want to use the dependcies separately since Delphi won't allow you to have duplicate unit names in installed packages.
Also, the reason you don't want to use DCUs is the fact that the DCUs are compiled for a specific platform and compiler. So unless you are sure that all devolpers are on the same platform ad using the same version of Delphi, dependency code needs to be recompiled.
Again, AlexSC has the best answer and InnoStudio is a great little tool.
I am trying to create an installation disk with InstallAware Express for my Delphi 2010 application. I have selected (checked)
CodeGear Database Express12
CodeGear Visual Component Library 12
for Application Runtime.
When I try to build it, I will get an error message
Error during build: No files matching pattern "C:\Windows\system32\*120.bpl"
The message will go away if I un-check the above runtime but of coz the program will not run.
Can someone please tell me what I am doing wrong?
Also... I have use their scan file button to scan the dependent files base on my application.exe and installaware put a list of files in the $TARGETDIR$, should I leave them there or I am suppose to move them to various folder (e.g. some of the files are from the windows\system32 directory...)
Thanks a lot.
FWIW, one of the great things about Delphi is that you can pretty much install on any system without worry if you turn off the "build with packages" option. This would eliminate the need for these files, and solve your problem, and also make the application more robust against updates and changes. IMO packages are only needed if you are building multi-module applications which are more advanced, and in that case you wouldn't want to be using any Express installer.
You can manually add the files.
To find out which VCL packages your application uses, open the project in the IDE. Use the menu item Project->Build project to rebuild your entire application, and then use Project->Information to view the information dialog. The list of packages actually required by (and therefore needing to be distributed with) your application are listed there.
Where to install them on the destination system depends on why you're using packages in the first place. If you're using runtime packages simply to reduce the download size for your users, and the packages will only be used by this single application, put them in the same folder as your application ($TARGETDIR$). If you're using them because you've got several different applications, and they'll all be installed in different locations but use the same runtime packages, install them in the System32 folder ($SYSDIR$, if I remember correctly).
InnoSetup works fine with runtime packages manually added, btw, especially if you use the excellent (and also free) ISTool IDE. (Not affiliated in any way; just a happy customer.)
Did you have Delphi 2010 installed on this machine? If so, you should see several bpl files under C:\Windows\system32 folder.