What to put in library path in Delphi IDE - delphi

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.

Related

Can one build an EXE project against a BPL/DCP with "Build With Runtime Packages" unchecked, based solely on the BPLs/DCPs?

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.

Using package in a project

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)

How does Delphi 7 find all the dcu files during compilation?

I am helping a coworker set up his computer so that his Delphi 7 environment works like mine. He has Delphi 7 installed plus the third party tools we use. We have a Delphi app with source. It compiles fine on my computer but when he compiles it on his computer, it keeps coming up with 'file not found' errors for many dcu files. These are dcu files of third party components, either which come with Delphi IDE or have been installed manually.
I renamed his C:\Program Files (x86)\Borland folder and copied my whole Borland folder structure to his so that he has what I have. So now his Delphi IDE and the app structure resembles mine, yet he still gets missing dcu's. Every time he gets a missing dcu, he adds its path to Delphi's 'Search path' list. For some dcu's, they exist in different folders which means we have to troubleshoot further to make sure we picked the correct version. My 'Search Path' is empty as shown below which tells me my Delphi doesn't use this entry to search for dcu's. Our computer's PATH environment variable entry has the same values for anything related to Delphi.
My question is why my delphi app compiles fine as it finds all the dcu's it needs which reside in different folders yet his Delphi is not finding them when we have the same folder structure and PATH?
How does the Delphi IDE finds all the dcu's it needs during compilation? What is left now to look at is the registry. Are the search patterns in the registry? Where? (We also have Delphi XE installed if this means anything)
You don't want to add these directories to your project's search path. That will make it so that only this project is able to use these components. Instead, you need to do this in the global library path, which applies for all projects. Check the library path of your existing installation, surely you'll find a large list of directories here.
Main Menu -> Tools -> Environment options dialog -> Library page -> Library Path edit box
They are the output paths, try looking in the following location
Tools > Options > Environment Options > delphi Options > Paths and Directories
This tells the IDE what source files to include. The only other difference can be if you system variables are different if you have any.
http://docwiki.embarcadero.com/RADStudio/XE8/en/Library

Delphi - locating path of a unit which the compiler can not search in its default path

I have downloaded a component that has many packages in it, then I have install all the design time packages and generated all the other dcu files.I have to assign its path in Delphi search path every time I create a new application. Is there a way to assign its path to Delphi compiler search path once and all application will get access to these unit, so that I need not to manually set every time the path for a new application.
If you want to have some component automatically available for every new projects you need to change the default Delphi IDE options - specifically path locations - so that Delphi IDE knows where to find needed files.
You do this by going into menu Tools -> Options. Then in the TreeView which is used for splitting the options into multiple categories you select Enviroment Options -> Delphi options -> Library.
On the right side of the window you will now have different options regarding the path locations for libraries and source files.
In order to allow Delphi to find needed precompiled units of your component you need to add the folder in which they are located to Library path.
In order to allow Delphi to find source files of your component you need to add the folder in which they are located to Browsing path.
You can read more information about these settings in the Delphi documentation which is also available online here:
http://docwiki.embarcadero.com/RADStudio/XE6/en/Library
Note if you don't own Delphi XE6 but one of the previous XE versions simply change the webpage URL by replacing "XE6" with the one you own.
EDIT: I have edited my answer to provide more specific information. Old post below:
If you got to Tools -> Options (or is it Enviroment Options in latest versions) you can set Default options for the Delphi IDE. These options also include the Default path settings which will be automatically used in all new projects.
The way I do this is to have a folder "Lib2" which I use as the unit output directory whenever I compile/install components - I let the components (I mean their source files, etc) be installed whereever they want).
(I call it "Lib2" because traditionally Delphi has placed its own DCUs in a folder called "Lib", and putting all the third-party ones in a folder separate from that one avoided having to re-install Delphi if my set-up got into a mess.)
If you do that, all you need do for new projects is to include the path to that folder in the project search path and set that as the default search path.
The way to do that varies with Delphi version - the D7 era it was just a question of ticking the "Default" checkbox on the Directories/Conditionals tab of Project | Options. The only minor problem is that sometimes the component needs a resource file; if the compiler complains about that, just copy it to there manually.
In XE4, there are several ways of getting Delphi to find compiled DCUs that you've send to Lib2 or whatever you care to call it:
The simplest seems to to do what the other answer suggests, namely add the Lib2 path to the list of Library paths under Tools | Options. The compiler will then use the DCUs it finds there without needing to be able to finds their sources, which is generally a good thing (see "btw" section below).
A second way is to create a project "Option Set" (see the OLH for details of what they are and how to create one, and then edit it (again, see OLH) to include Lib2 in the list of search paths. After that, you can apply that Option Set to any project which it suits. There may be a way to automatically apply your Option Set to new projects, but I haven't managed to find it yet. In any case ...
A third way is to add a project which has Lib2 amongst its search paths to the Delphi repository and then create new projects that you want to use Lib2's contents from this entry in the repository.
Btw, there is an important practical point to having 3rd party libraries and any of your own standard ones output their DCUs to your Lib2 or equivalent. Because the compiler can find the compiled DCUs there, it does not have to be able to find the source code of those libraries in order to be able to compile your project. Isolating the compiled DCUs in this way helps avoid the dreaded "unit x was compiled with a different version of y" error message (y usually being a bpl) which has been the cause of so many cries for help in Delphi newsgroups over the years.

Moving to use of Delphi packages - best practice please?

I am trying to start making my own libraries avaialble as packages prior to compiling my Apps with these packages hence modularising my code. For years I've 'sort of' understood packages, breathing a sigh of relief when I load a component package and click on 'Install' and it does. I understand that the process of installing a component (or components) is via the creation of a BPL which is then registered with the IDE.
Where I begin to get lost is how to make files available so that I can compile with EITHER a package OR pre-compiled dcu's (like the third party vendors do) and without pointing my project at the source code all the time. I can create a package with the following settings:
where I've specified that all my output will go into 'c:\scratch\wow'. After a build I find TEST.BPL, TEST.DCP and lots of DUC's. Now, when I point another project at this folder to use the DCU's, I get a missing DFM error (one of the units is a form). Should I be manually copying needed DFM's into this output folder? The DPK knows about this form, so why do I not get the DFM copied for me? I presume that using TEST.BPL, that file contains everything, but I wish to work in the two modes. Of course I can get around this by including the source folder in my project search path to find the DFM but third party libraries seem to already have the DFM's in their output folder. Did they install them there using the installer?
Thanks
instead
As others say you could use post-build events to copy your DFM files into place. Other people use a one-time external batch file that copies the DFMs to the DCU folder.
Personally I see very little benefit to making packages for things which are not developed also as reusable components. I also see very little benefit in partitioning an existing application into packages, when you don't reasonably need to use the same subsection or package more than once, or at designtime.
Things I would put into packages:
Delphi visual and non-visual components.
Things which absolutely must be plugged in at runtime, or left out. For example, supposing I sell MetaWare Light and MetaWare Pro, and instead of using compiler IFDEFs to build a differnt binary, I preferred for some reason to simply not ship the ADVANCEDFEATURE.BPL with my systems.
Things to beware of with packages:
I have run into a lot of compiler bugs when combining packages with generics. I have also run into IDE crashes and lockups, in Delphi 2009, 2010, XE and XE2. (I believe XE3 is better)
You should learn a bit about BorlandMM.dll and shared memory management in the BPL world before you move to it. There are some subtleties.
Packages limits the ability of the linker to decide what to remove. In fact, it pretty much destroys it. Packages contain everything that is linked into them, and nothing publically accessible can be removed.
Once you've created a binary package and shipped it to even one customer, you have a pretty difficult to modify contract (this BPL contains a particular signature or application binary interface) you have to be careful in the future to never change them, or mix and match them. Beware of DLL hell, even among your own customers, and be prepared to use versioning on your packages. Just as delphi packages have a version suffix, I recommend you use version suffixes in your own packages right off the bat, and bump them whenever binary compatibility has changed.
Delphi handles build dependencies between packages about as well as could be hoped, which is less well than a single monolithic application. In applications that I have that make heavy use of packages, I find project groups that contain a bunch of packages that depend on each other are very difficult to manage and build quickly. In fact, I have experienced that both compiles and builds are slower and more frustrating than they would be in a singular 750Kline megaproject.
I really wonder if you're not that into the package area of Delphi (you breath a sigh of relief whenever a delphi component actually builds and installs without issue?) if you really want to move into the Packages World totally. By all means, you should experiment. But I wouldn't bet the farm on it yet. Learn some more first.
Yes, you should copy the .dfm to the directory with the compiled units (.dcus), if that is the only directory you want in your search path. The BPL will of course contain the .dfms, and you need a .dcp to be able to link a BPL with your app.
Third party tools must have put the .dfms together with the .dcus in the directory using their installer, indeed.
Instead of copying *.DFM manually you can use Post-Build Event (Project/Options/Build Event), ex:
copy “$(PROJECTDIR)\Unit1.DFM” “c:\Scratch\wow\Unit1.DFM”
I found a way to do this without moving .dfm files to the directory of .dcu files, so you can have a directory for .dcu files only one for .dcp files only and another for .bpl files only.
All you need to do is to create another directory on your good structure, as I do. The directory is called RES and in it should be placed all the resource files (.res files, not .dcr files) that are used by applications compiled using your packages (components). In the Delphi Library Path, you must include in addition to the DCU directory (you should already have) a directory named RES.
On your component (design time) do everything you want with the form (design it, put other components, etc). In the source code of the unit you replace {$R *.dfm} with {$R UnitName.dfm}. In doing so, save all and close the DPK. Now move the .dfm file (do not copy, move!) to the RES folder (the .dfm file is a resource file to the Delphi. The {$R} directive is proof!) and after that open the DPK again to understand what has changed.
First realize that you may not open the form (F12) from his unit, though no error was issued by Delphi about "DFM missing".
Now, do a Build on your package and then install it. Realized again? No errors displayed! This happened because you have indicated the location of .dfm file in the Delphi library search path (RES directory).
Done! You can use your component and dfm will be found when your component is included in an application.
Many of you can now say that this way I will not longer be able to visually edit a form in the component design time. Yes this is true, but if you think about it, why would I want to change so often a form into a component that, in practice, should only be used and slightly edited? Draw your own conclusions ;)

Resources