Well, it finally got to me. I have spent literally YEARS
tweaking Delphi DPROJ files culminating in a big issue where my projects would
remote debug in Delphi 7 but not in any later Delphi IDE. Despite
a lot of help and suggestions from you all over at StackOverflow I lived
with this for a while but because the source had all been moved over to Unicode
there came a point where I just HAD to get remote debugging working.
Finally, a solution. It turned out that because my projects
have been through almost every Delphi IDE since Delphi 1.0 (I’m now on XE3),
each IDE has had a little fiddle with the DPROJ file – I compared my old file
with that created by deleting it and letting the IDE recreate it and there was
just loads of stuff, mostly unintelligible. I suppose that it is logical that
with such a complex XML file with so many options being fed into MSBUILD that
like the registry, it’s easy to add but only a reformat cleans it properly.
So, I’d discovered that deleting the DPROJ’s and letting
Delphi recreate them was GOOD. The BAD thing was that I then had to re-enter
the search paths and compiler / linker settings for each one. This is a massive
task and very prone to error. For example I have 84 DPR files in my general
low-level library and some 500 DPR files under active management. There has to
be a better way.
There was an interesting discussion where it
was proposed that you do not publish your DPROJ files due to the fact that
they are so full of data some of which is very local in nature. Whilst I agree
that this promotes cleanliness, personally I commit every project DPROJ to our
repository because without them it is not possible to quickly build a project.
You can NEARLY get there with relative paths for each file specified in the DPR
but there are still some settings that Delphi only gets from its DPROJ and
which you WILL want to set. With the advent of the PaServer remote connector
tool for cross-platform debugging, important profile information is stored in
the DPROJ.
For a few IDE’s now the built-in
IDE Configuration Manager has been tempting. It allows you to switch build
configurations across multiple projects and allows the use of Option
Sets. This is very exciting because it appears to allow an ‘empty’ DPROJ (i.e.
one that you have just let Delphi re-create from the DPR) to have attached by
reference a common *.optset file that actually contains your settings. Since a
project folder might have many (in my case 90-odd) projects each of which are
likely to need the same paths and settings this would be great. Sadly, at time
of writing (XE3 17.0.4625.53395) I could not get relative paths in the common
optset file to be brought into the MSBUILD source correctly (the same paths
placed directly into the project options worked fine).
So, enter my new tool DprojMaker.
Flushed with a little understanding about what parts of the
*.dproj files mean I decided to compare a ‘virgin’ DPROJ file which Delphi
recreates for you if you don’t have one and the ‘good’ DPROJ file after you
have placed a few useful project-specific settings into it. Not surprisingly
there is little difference between two similar projects, only name, GUID etc.
So I set out to take a working DPROJ file and to replace it’s project specific
parts with common marker tags that could be later replaced with the info that
you want. So for example the original DPROJ file started with:
<Project
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{4FCD3454-5FBC-42E3-8497-0D52C905AA89}</ProjectGuid>
<MainSource>ArtFixtureLayoutManagerTest.dpr</MainSource>
<Config
Condition="'$(Config)'==''">Base</Config>
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
<ProjectVersion>13.4</ProjectVersion>
<Base>True</Base>
<AppType>Application</AppType>
<FrameworkType>VCL</FrameworkType>
The highlighted items are specific to your project, the
rest of the data appears in ALL projects. By replacing these items with
replacement marker tags such as:
<Project
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>$P(ProjectGuid)</ProjectGuid>
<MainSource>$P(AppName).dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<FrameworkType>None</FrameworkType>
<ProjectVersion>14.3</ProjectVersion>
<Platform
Condition="'$(Platform)'==''">Win32</Platform>
I then set about creating
a tool to automate this process with the target of having a per-folder ‘DPROJ
template’ (or even a single file for general use!) and simple configuration
files that specify what data is to patch this template.
This has been great. I now
simply delete ALL my dproj files in a folder and replace them with a single
config file that looks similar to:
[General]
InputName=.\DprojMakerTemplate.dpminput
AppName=Get(ProjectName)
ProjectGuid=Get(RandomGuid)
DCC_Define=madExcept
MapFile=3
DCC_UnitSearchPath=..\..\paslib32\src\Paslib32;..\src\ArtDBfLogFile;
DCC_ExeOutput=$(ArtExeOutputRoot)\Art\ArtDBFLogFile
RcCompile=
Hopefully the *.optset
option set solution will improve to give us predictable operation and ideally
some logging to debug how multiple files are combining our data.
View comments