In Delphi (Berlin), I create a new win32 package and component. I compile it and it creates the default Unit Output Directory of .\$(Platform)\$(Config). Now after installing I need to set the System Library Path correctly so that I can use it in new applications. Should I set this to the dcu path (.\$(Platform)\$(Config))?
If I do, I then need to compile the component for each variant of platform and Config that needs to be supported [(Win32/Win64)/(DEBUG/RELEASE)].
Is this correct? Maybe it would be better to always point to the RELEASE path?
Related
The editor automatically adds the System.Actions unit when one of my forms is saved.
It compiles without a problem in the IDE, but unfortunately the Command Line Compiler can not find the file and gives me the error:
Error: F1026 File not found: 'System.Actions.dcu'
What am I missing?
In what follows, I am assuming that you are using msbuild to compile your program.
The System.Actions unit was added in XE3 to support actions in both FMX and VCL frameworks. Prior to that release FMX had no actions. Some classes were moved around, out of VCL units and into the new System.Actions unit which can be used by both FMX and VCL code.
So, the compiler error that you see suggests to me that you are unintentionally compiling with a version that pre-dates this change. My guess is that your IDE is XE3 or later, but that your command line build is configured to use an earlier version of Delphi. Most likely through the PATH environment variable, and whatever Embarcadero entry happens to be first in that variable.
If my hunch is correct then you need to ensure that you compile with the desired version.
The way I organise machines that have multiple Delphi installations is as follows:
Remove all Embarcadero entries from your PATH environment variable.
Whenever you need to build at the command line, configure the environment, for instance by running the appropriate rsvars.bat script (found in the bin directory of your Delphi installation) before you call msbuild.
This way you cannot accidentally find the wrong version because you have to explicitly configure an environment.
On the other hand, perhaps you are calling dcc32 directly. Don't do that. You will have to supply all the options and paths that are already defined in your project file. Repeating that is just a way to create a maintenence headache and make it likely that your command line build won't match the IDE build.
Instead, use msbuild to build your program. That way you can use the settings defined in your project file.
Thanks Hefferman for your advice but we shall stick with dcc32. It's easier to customize. For example we didn't figure out how to use more than one 'define' parameter with msbuild. It's possible to use dcc32 with the -NS switch for dependent 'uses' and that is our solution. We also create some .dpr files with code and in that case we do not have a corresponding .dproj file.
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 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)
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.
Is there a way to instruct DCC32 to use the same library path that is used by the IDE (i.e. in Tools/Options/Environment Options/Delphi Options/Library - Win32)?
For obvious reasons, I do not want to maintain two lists of directories (one in a cfg file, one in the Delphi IDE).
If you are using Delphi 2006 or later, you can use MSBuild instead of dcc32, and MSBuild will use the same search path as the IDE
You should have a cfg file in your project directory called yourprojectnamedpr.cfg which actually should contain all the directories defined in the IDE for that project.
It is a lot of work to use DCC32 to build from the command line. MSBuild is far easier. The library path is stored in the registry, but the location depends on the Delphi version, for example (python code):
if BDSVER == '5.0':
CompanyText = 'Borland'
else:
CompanyText = 'CodeGear'
key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,'Software\\' + CompanyText + '\\BDS\\' + BDSVER + '\\Library')
IncludePath = _winreg.QueryValueEx(key,'Search Path')[0]
# Then you must replace the environment vars $(BDS), $(BDSCOMMONDOR) etc
IncludePath = ReplaceEnvironVars(IncludePath)
And there is much more to do. You must also obtain the search path, and you must obtain conditional defines from the .dproj file, etc.
I wrote a complete automated build tool in python (for BDSVER >= 5), back when Delphi 2007 installed on XP x64 had a broken MSBuild. Later, it turned out that some required configuration files were not copied into the correct .NET folder by the Delphi installer. Copying these files to the correct location fixed the problem, and now I use MSBuild.
This works for me:
call "C:\Program Files (x86)\Embarcadero\Studio\19.0\bin\rsvars.bat"
msbuild project.dproj
If you use an older Delphi (e.g. Delphi 7), you must put all your information in the "Search Path" Directory option in your IDE. It will be saved in your .dof file. The .dof file is the main reference of your project.
The IDE will also automatically update the .cfg every time you change the project configuration. The .cfg is the specifies the compilation option for the command line compiler. Both the .cfg and the .dof must be under version control.
If, instead of editing your .dof file from the IDE, you manually edit it, you can use the dof2cfg utility to generate a new .cfg from your .dof. You will have to put it in your build chain.