Jump to content
HaSo4

Best strategy to set up global Release/DebugDCU paths in the IDE, as example for Spring4D DCUs

Recommended Posts

Hello Delphi community,

I'm unsure about the setup for Delphi 13 Patch 1 library paths.
Usually I do this with the editor in Delphi under Tools/Options/Language/Delphi/Library/

image.thumb.png.ca04fcf63bab0e640cf84369db8e67d9.png

 

 

Since I've installed the Spring4D library by its build.exe and moved its DCUs to another folder,
I wanted to ease the whole setup process by editing the general EnvOptions.proj File under C:/User/AppData/Roaming/Embarcadero/Bds/37.0/*.*
There is has entries like this 

...
<DelphiLibraryPath>$(BDSLIB)\$(Platform)\release;$(BDSUSERDIR)\Imports;$(BDSUSERDIR)\Imports\$(Platform);$(BDS)\Imports;$(BDSCOMMONDIR)\Dcp;$(BDS)\include;C:\MY_DCUs\Vendor\Spring4D\Rx1301\Win32\Release;$(BDSCatalogRepository)\VirtualTreeView-13\2025.03\source\</DelphiLibraryPath>

...

<DelphiDebugDCUPath>$(BDSLIB)\$(Platform)\debug;C:\MY_DCUs\Vendor\Spring4D\Rx1301\Win32\Debug</DelphiDebugDCUPath>

which would be an easy find&replace for all platforms:

Spring4D\Library\Delphi13\Win32\
Spring4D\Library\Delphi13\Win64\
Spring4D\Library\Delphi13\OSX64\
Spring4D\Library\Delphi13\OSXARM64\
Spring4D\Library\Delphi13\iOSDevice64\
Spring4D\Library\Delphi13\iOSSimARM64\
Spring4D\Library\Delphi13\Android\
Spring4D\Library\Delphi13\Android64\
Spring4D\Library\Delphi13\Linux64\

 

This is how I replaced all these in the global EnvOptions.proj file and thought the IDE will take these values from the next start.
But it seems doesn't, because there were copies stored under HKCU/Software/Embarcadero/Library too, which seems to override these settings fully or partly.
Located here:
[HKEY_CURRENT_USER\Software\Embarcadero\BDS\37.0\Library\Win32]
[HKEY_CURRENT_USER\Software\Embarcadero\BDS\37.0\Library\Win64]
and so forth.

What is the best strategy for changing these global libraries in a central place, so that they remain permanently in the IDE?

One way could be to simply delete the [HKEY_CURRENT_USER\Software\Embarcadero\BDS\37.0\Library\* folder, in the hope that the IDE will restore it,
from the EnvOptions.proj file.
Is that possibly working, before I crash my whole installation?

Who can help to find the best strategy to ease these setups, because visual editing more and more platforms in the IDEs tools editor is somewhat cumbersome.
 

image.png

Edited by HaSo4

Share this post


Link to post

I would define an environment variable for the Spring4D root folder (e.g. Spring4D= C:\3rdparty\ Spring4D\Library\Delphi13) in the IDE options and then just add

$(Spring4D)\$(platform)\$(config) to the search path in a projects "all projects  - all configurations" options. Messing with the IDE registry settings is too fragile for my taste.

Share this post


Link to post

Thanks for the proposal, that sounds like a good approach too, I will try that later.
Unfortunately the initial settings were added during the Spring4D build.exe setup, perhaps I could try to uncheck the "Update Delphi Registry" option,
which maybe proceed no library path settings at all.
image.thumb.png.1dff3bfd88277577667b022c62028061.png

 

Nevertheless, this issue points me to the more general question, where are those settings stored and how to be handled.

Would be great to know what measures are save to be used.
Editing a few paths URL should not be that system critical.

One option could be to export the whole Library entry from the RegEdit, then edit it and import this back into the registry.

I'm looking for some streamlined IDE configuaration workflows, for multiple platforms, to make the developers life a bit easier.
 

Edited by HaSo4

Share this post


Link to post
35 minutes ago, HaSo4 said:

I'm looking for some streamlined IDE configuaration workflows, for multiple platforms, to make the developers life a bit easier.

My advise would be to not use global library paths at all, unless you absolutely have to.

 

I generally use project library paths instead, keep paths relative to the project folder, and reference the source folders instead of the dcu folders.

The advantage is that projects are self-contained and can easily be moved to another location or shared with others (e.g. a build server) via version control (3rd party libraries are included as Git sub-modules under the source folder).

Share this post


Link to post

I would not call it "global paths", but I simply want to put the automatically generated DCUs into a well defined place, some levels up.
The reason is, that I have a Vendor folder, which includes a few 3rd party libraries sources, which usually generate their local DCU folders into it too.

The desired structure is similar like this:
VendorSrc/Spring4D/Source/*                                    <-- just for the sources 
VendorSrc/Spring4D/Library/Delphi13/Debug/*     <-- from here
VendorSrc/Spring4D/Library/Delphi13/Release/*
VendorDcu/Spring4D/Library/Delphi13/Debug/*   <-- to there
VendorDcu/Spring4D/Library/Delphi13/Release/*

 

The DCU's pollute my VendorSrc folder, which should contain only sources, in an ideal case.

I used to have project based libraries in the past, but I wanted to change back to the usual Tools/Options based folders.
The problem with project based paths is, that they doesn't always work well for me, especially with pre-defined debug DCU's.
The right way should be using Tools/Options based folders, isn't that the case?

 

Edited by HaSo4

Share this post


Link to post
45 minutes ago, Anders Melander said:

I generally use project library paths instead, keep paths relative to the project folder, and reference the source folders instead of the dcu folders.

The advantage is that projects are self-contained and can easily be moved to another location or shared with others (e.g. a build server) via version control (3rd party libraries are included as Git sub-modules under the source folder).

What if you have dozens (or even hundreds) of projects that use the same set of libraries? Then you have copies of those library source files duplicated many times right? (I'm not being critical, just trying to understand how that would work.)

 

46 minutes ago, Anders Melander said:

My advise would be to not use global library paths at all, unless you absolutely have to.

I, too, keep global library paths to a minimum. But what I do (not sure if this is the best approach) is libraries, 3rd-party components, etc. all compile out to $(BDSCOMMONDIR)/Dcp/$(Platform). So the libraries are kept separate but all point to a generic location (I've never had a filename conflict) and my library path includes that "dcp" location, which is also separate but consistent between versions of Delphi.

Share this post


Link to post
52 minutes ago, corneliusdavid said:

What if you have dozens (or even hundreds) of projects that use the same set of libraries? Then you have copies of those library source files duplicated many times right?

Yes. Is that a problem?

 

When I work on a project, I focus on that project. Whatever other projects, that I'm not working on, do is not relevant - even if they use the same 3rd party libraries (which they do - and for example DevExpress is something like 2500 files).

 

Besides, if you are working under revision control (like you should) then you have to use local copies.

 

56 minutes ago, corneliusdavid said:

I, too, keep global library paths to a minimum. But what I do (not sure if this is the best approach) is libraries, 3rd-party components, etc. all compile out to $(BDSCOMMONDIR)/Dcp/$(Platform). So the libraries are kept separate but all point to a generic location (I've never had a filename conflict) and my library path includes that "dcp" location, which is also separate but consistent between versions of Delphi.

Design-time is another problem. I let the libraries install to whatever location they want and put the dcp/bpl files where they want.

 

So for example I have DevExpress installed in one global location for design-time support, but each project also have their own copy of the DevExpress source via a Git sub-module, because I need to have all the source under revision control. I only compile/link against the global copy for ad-hoc stuff or open source projects.

For the few cases where I work on older version of a project, and need the correspond older version of the libraries at design-time, I launch Delphi with a custom setup via my DelphiLauncher script. But it's rare.

 

1 hour ago, HaSo4 said:

The problem with project based paths is, that they doesn't always work well for me, especially with pre-defined debug DCU's.

I don't use library dcus shared between projects. I always compile against the source and place the generated dcus in ..\Lib\$(Platform)\$(Config) or something like that. I.e. paths relative to the project.

Share this post


Link to post
10 minutes ago, Anders Melander said:

Yes. Is that a problem?

 

When I work on a project, I focus on that project. Whatever other projects, that I'm not working on, do is not relevant - even if they use the same 3rd party libraries (which they do - and for example DevExpress is something like 2500 files).

Well, not with today's disk sizes, I guess. But that's still a LOT of duplicate files. It goes against my "minimalist" mindset, probably stemming back to when HDs were smaller and more expensive.

12 minutes ago, Anders Melander said:

Besides, if you are working under revision control (like you should) then you have to use local copies.

Of course I have revision control. I have libraries under a \lib folder, separate from the project folders; there is a git repo for each.  Then each project (or suite of projects) has a git repo as well. There is nothing that is not under revision control. But not everything for a project is lumped together under one project-folder. If I have to set up a new computer, I first get all the libraries and components established, then I load the projects which point to those $(BDSCOMMONDIR) folders like they do on other machines and I'm good to go.

 

Perhaps one reason I shy away from putting libraries under project folders (besides my aversion to duplicating files) is I find dealing with git sub-modules to be a pain. Perhaps I simply haven't tried hard enough to learn how to manage them but I always seem to mess them up.

 

Another reason, I often do a build all and don't like to have library source in the paths because then it recompiles EVERYTHING; once debugged and unit-tested, libraries should never have to be recompiled; if you have a large set of library code, recompiling a project would take a lot longer than it needs to be.

25 minutes ago, Anders Melander said:

For the few cases where I work on older version of a project, and need the correspond older version of the libraries at design-time, I launch Delphi with a custom setup

I maintain projects in a variety of versions of Delphi. My job only deals with Delphi 5 and 12 but I maintain several old projects for clients that for various reasons are "stuck" in old versions of Delphi. I use Delphi 7, XE, XE2, and 10.4, so keeping library code out in $(BDSCOMMONDIR) is consistent among projects while being in separate folders because each version of Delphi defines that constant uniquely. I can see where keeping library source as local sub-folders to each of those projects would be a benefit but could also become a git-repo-update nightmare as you make a change in one project's library then try to merge it with another project's library source that has a different change.

Share this post


Link to post
12 hours ago, HaSo4 said:

What is the best strategy for changing these global libraries in a central place, so that they remain permanently in the IDE?

Update the registry. That is the source of truth. The EnvOptions.dproj file is updated when Delphi IDE is open. 

 

Quote

The DCU's pollute my VendorSrc folder, which should contain only sources, in an ideal case.

Why? Delphi has been working like that since forever. Most development platforms to the same, i.e., create binary, unversioned files in the same repository as the source code. That's what .gitignore is for. Specially for 3rd party, vendor software where you couldn't care less for the source code.

 

Nevertheless, you can try installing Spring4D using TMS Smart Setup. It has a feature of mega folders where you can define where the DCUs will be located for all or each product you install:

 

https://doc.tmssoftware.com/smartsetup/guide/configuration.html#using-dcu-megafolders

 

Share this post


Link to post
16 hours ago, Anders Melander said:

My advise would be to not use global library paths at all, unless you absolutely have to.

That is currect, in the case that you mean absolute paths, but for those experiments how it behaves, this shall make no difference.
Those absolute paths came originally from Spring4D in the first place, which were listed in the EnvOptions.proj and HKCU_..._Library.
Thats why I keep it as is, because I don't know what side-effects they may have in other places.

I still try to figure out the whole concept of storing from the IDE in two different places.
If manual changes in the IDE seems to land into HKCU_..._Library, why to have a copy in EnvOptions.proj at all?
My first idea was the EnvOptions.proj is only a kind of template, for the first IDE start, but my tests seem to say that its not the case.

 

7 hours ago, Wagner Landgraf said:

Update the registry. That is the source of truth. The EnvOptions.dproj file is updated when Delphi IDE is open. 

Thanks, thats clearly matches with my tests here.
It would mean its vice-versa than I expected, editing the HKCU_..._Library entries would land into EnvOptions.proj, I will check if it behaves like that.

 

7 hours ago, Wagner Landgraf said:

Nevertheless, you can try installing Spring4D using TMS Smart Setup. It has a feature of mega folders where you can define where the DCUs will be located for all or each product you install:

Thanks for pointing to this, I was not aware of this tool.
Also to bring in the option of symbolic links opens some new ideas.

For me its clear now, I have to edit the HKCU_..._Library settings, in case I want them took over in the IDE.

Share this post


Link to post
6 hours ago, HaSo4 said:

If manual changes in the IDE seems to land into HKCU_..._Library, why to have a copy in EnvOptions.proj at all?

For command-line compilation using msbuild to work. msbuild is Microsoft tool which doesn't use the Registry, it uses a chain of xml-based project. 

EnvOptions.dproj is one of them, thus the IDE updates it according to the Registry for msbuild to work.

 

 

  • Like 1

Share this post


Link to post
23 hours ago, Anders Melander said:

My advise would be to not use global library paths at all, unless you absolutely have to.

 

I generally use project library paths instead, keep paths relative to the project folder, and reference the source folders instead of the dcu folders.

The advantage is that projects are self-contained and can easily be moved to another location or shared with others (e.g. a build server) via version control (3rd party libraries are included as Git sub-modules under the source folder).

Not only that I don't agree, I recommend the opposite and for a good reason:🙂

 

Scenario

Imagine  you have Project1 that uses Library1 (Spring4Delphi or something else).

 

1. If you give your project to someone else and you have the DCU paths (for Library1) in the DPROJ file, you FORCE that person to install the dependent library (Library1) in exactly same place as you have it on your computer. If the user already has Library1 installed in his computer, he will have to change project's options. So, it is clear that this way of using paths is not portable.

 

2. If you use the IDE "Library paths" then the the information about the Library1 is not included in your project. If the user receiving your project already has Library1 installed (and he was smart enough to use IDE "Library Paths") then Project1 will compile in his computer without any modifications. 

This is the exact purpose of "Library paths": to keep the external libraries/dependencies separated from your projects!!!!

 

-

Delphi's help:

1.thumb.jpg.59719a0038678f7850692b0e168c6450.jpg

Spring4D is a package!

_

 

This is exactly what Delphi does: when you create a new project you don't have to specify where Vcl.Dialogs or System.SysUtils DCUs are for that project. The project can already find them because they are in the Library Paths. 

Why reinventing the wheel? 

 

_____________________________________________

 

Quote

> and reference the source folders instead of the dcu folders.

 

This could also be bad advice if you have truly large projects. Why adding another few seconds to your already-2-minutes-long-compilation-time when you could use precompiled DCUs? 

 

Again, this would be counter-Delphi-way: When you start a new project in Delphi, you don't compile the Vcl.Dialogs.pas or System.SysUtils.pas. Your project will find and use the precompiled DCUs.

 

_____________________________________________

 

I think paths are one of the least understood parts of Delphi, and therefore the most abused. 
I upgraded several large projects to use precompiled libraries and I showed off really big amounts of times from the compilation time, with no downsides. 

For most of my personal programs, the project (DProj) "Search Paths" are empty. 

 

God gave use Library Paths for a good reason. Let's use them. 🙂 

 

Edited by GabrielMoraru
  • Like 1

Share this post


Link to post

Hard-coded paths like this can also be modernized by replacing it with $(Auto) and $(ProductVersion).

Next time when you install a new Delphi version, you won't have to change the paths AT ALL, just recompile your libraries.

 

2025-10-04_154048.jpg.9c06f35e71dbf592597ba8161e941afa.jpg

 

Edited by GabrielMoraru
  • Like 1

Share this post


Link to post
1 minute ago, GabrielMoraru said:

If you give your project to someone else and you have the DCU paths (for Library1) in the DPROJ file, you FORCE that person to install the dependent library (Library1) in exactly same place as on your computer. If the use already has Library1 installed in his computer, he will have to change the paths.

Read what I wrote again.

 

With the system I described, a project can be deployed and ready to use anywhere, by anybody, in minutes. You just need to have Delphi installed.

We use the exact same setup with build servers (with only Delphi installed) and with team developers. Most developers just pull from the repo, start Delphi with the script and they are ready to go. No need to setup or install anything.

Share this post


Link to post
7 minutes ago, Anders Melander said:

start Delphi with the script and they are ready to go. No need to setup or install anything.

So, I guess (I guess only) you deliver the external dependencies (packages) without your project...

 

For small projects, under 2 mil lines, could work.
Still, against the way Delphi was built 🙂 

Share this post


Link to post
4 minutes ago, GabrielMoraru said:

So, I guess (I guess only) you deliver the external dependencies (packages) without your project...

I don't know what you mean. Everything is under revision control, including 3rd party source (for build) and package binaries (for design-time).

 

7 minutes ago, GabrielMoraru said:

small projects, under 2 mil lines

Is that meant to impress?

The whole system obviously works better for large projects than for small ones as it takes some time to prepare for use. I wouldn't bother with adhoc projects.

 

23 minutes ago, GabrielMoraru said:

Still, against the way Delphi was built

Yes, but fortunately we no longer do things like we did in the 90s when Delphi was designed. Delphi has just completely failed to evolve in this area.

Share this post


Link to post

As far as I can see, the TMS SmartSetup tool goes a long way towards bringing Delphi into a more modern system of being able to deploy packages rapidly and efficiently. It needs some more examples at the moment to  make it accessible, but it seems to be competitive with tools that have been in Python, .Net etc for decades already that we are missing.

  • Like 3

Share this post


Link to post

@Anders Melander - in your approach, how do you handle DLLS? Some third party packages come with DLLs that have to be put somewhere on the system path.  Of course, when you switch to an old version of your program, you also need to switch to the old version of the DLLs..

Share this post


Link to post
1 hour ago, Dave Novo said:

how do you handle DLLS?

I don't explicitly handle dependent DLLs but...

BPLs are basically just DLLs and, since one package can depend on another. I handle that by adding the package folders to the system search path. This also takes care of dependent DLLs.

Note that the search path is altered only for the current session (read: the running Delphi IDE process), so the global environment isn't modified.

Share this post


Link to post

What @Anders Melander is advocating is closer to how people work in python.   For every project you create a self-contained virtual environment that includes all the dependences.  Python has the tools to make this workable and fast.  The equivalent in Delphi would be to have for every project a virtual machine with the required version of Delphi installed and just the dependencies you need.  But this is not as practical, with Delphi.   

 

FWIW, what I do for projects of moderate size (about 1m lines including dependencies) is:

  • Minimize the use of third party tools.  For instance, although I know that the Spring4D collections are better than the RTL ones and that there are faster JSON libraries than System.JSON I stick to the RTL libraries.  Having said that, PyScripter has 16 external dependencies, many of which I developed or maintain.
  • Only use open source projects with available source code, preferably actively maintained.
  • Try to use the latest versions of all dependencies and Delphi.  This sometimes leads to incompatibilities and troubles, but I think that the benefit of getting the latest features and bug fixes outweighs the trouble.  
  • My library paths point to the source code (typically in cloned git repos) and not the compiled dcus.   I know this will be frowned upon.  However, in my case it saves me time.   When a dependency gets updated, I just pull the latest updates from the git repo without having to install the components.  
  • When I upgrade to a new Delphi version, I use MultiInstaller to install all the dependencies in one step.  MultiInstaller can install dependencies from git repos, zip files or existing folders.  It can also install components in the 64 bit IDE of Delphi 13.  The whole process takes minutes not hours.
Edited by pyscripter
  • Like 3

Share this post


Link to post
On 10/4/2025 at 10:35 PM, pyscripter said:

The equivalent in Delphi would be to have for every project a virtual machine with the required version of Delphi installed and just the dependencies you need

That is not 100% true. Delphi has the -r (registry) feature where you can launch different instances of Delphi with different settings, including installed packages, library paths, etc.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×