Advantages of NOT versioning .dproj - delphi

I read in a blog about Version Insight (http://www.delphifeeds.com/go/s/77066) that (among others) JCL doesn't have its .dproj files under version control and i was wondering what the advantages of that would be.
Especially since me and my collegue developer often "bug" each other with checking in project files with our own favorite debug settings (he likes optimization on, I want it off). And because of the regular hick ups of Delphi 2007 that screw up the dproj file with all kinds of faulty dependencies. Does not versioning help in anyway with these things?
We are using Starteam as our VCS at the moment.

If you're using Delphi 2009 or later Option Sets are a perfect solution for this problem.
Option sets are basically collections of settings that would normally reside in the DPROJ (which you do version) but instead stored in a .OPTSET file (which you don't version).
Make your DPROJ contain the settings that are common to all developers, that nobody is allowed to change unless it's an agreed across the board change.
Next in the project manager (D2009 and above) on first the DEBUG configuration node and then the RELEASE configuration node, right click and select "New Option Set". Call this option set something like "Local Developer Debug Settings.optset" and "Local Developer Release Settings.optset".
Now commit only your DPROJ to version control as it now refers to these .OPTSET files. You must name your option sets exactly the same on each machine for this reason.
When you want to make a local change to your project configuration rather than editing the project configuration, right click on the Option Set in the project manager and select "Edit Option Set".
The IDE will apply the changed settings from the option sets without modifying the original DPROJ. Settings are applied hierarchicly with option sets being the last to be applied.

I store, in my .dproj files, settings that are used by msbuild for my build process. For example, conditional defines, compiler settings, etc. If you do the same then you need to version them.
If you are using a version of Delphi where the IDE breaks the .dproj file on a regular basis, then surely revision control will help you fight back.
I can't see any advantage in not versioning them.

If you choose not to version your DPROJ, when creating your release builds I recommend you use a separate build script of some sort that you do version e.g.
a batch file that calls the command line compiler and specifies the compiler options and paths required.
a Finalbuilder project (much easier than a batch file)
an msbuild script (never done this myself but I assume it would be possible).

One solution for this issue is to be more discerning about what parts of the DPROJ (and also DFM files) you allow to be checked in.
You don't mention what version control system you're using but TortoiseHg has a hunk selection feature as part of it's commit process which lets you select individual lines within a changed file to be committed and still leave other lines uncommitted.
I use this method to never check in junk changes from the DPROJ (such as changing the active config from RELEASE to DEBUG) and the DFMs (e.g. changes to ExplicitHeight and ExplicitWidth properties).

The only reason i can think of to NOT version control DPROJ files is if, like the JCL, you can regenerate them as part of your build process. The JCL is a class library (code-library) not an application, and it targets multiple versions of Delphi with differences in their .dproj files. In fact, versions of delphi prior to 2005 didn't use .dproj files at all.

Later version of Delphi XE4, 5, 6, and XE7 are very stable constructing the .dproj XML files. I have no complain using git to version .dproj and .groupproj files. Updates to these files using the IDE editor result to expected neat and clean changes only.

Related

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.

Package (BPL) Automatic Naming Suffix

I write a lot of components and libraries for Delphi, most of which require the use of BPL Packaging so that they may be installed into the IDE.
This is simple enough and works well, right up until you want to maintain a single set of Package Project Files (in a single Project Group), but also want to compile and distribute those same packages for different Delphi versions.
Up to now I've been creating a different Package Project for each version of Delphi, and explicitly defining a Delphi Version Identifier as a suffix (e.g. Kinect_XE.bpl and Kinect_XE2.bpl).
I am aware that, in the Project Options for a Package Project, under Description, there are the fields LIB prefix and (more importantly for my needs) LIB suffix.
I am further aware that if I place a value in LIB suffix, it'll be appended to the end of the compiled BPL's filename.
My question, however, is first whether it is possible to have the IDE automatically populate the LIB suffix field with the IDE/RTL Version number, and if so... how?
I'm fairly certain this is possible, as it would appear that vcl120.bpl (and its counterparts for each respective version of Delphi) can be Referenced (as requirements) of your own packages using just vcl rather than having to type the full vcl120. It is, in fact, this same behaviour I'm hoping to achieve... where my packages can intra-reference eachother (as neccessary) without having to provide version-specific references to accommodate the suffixes.
Equally important is that resolving this will enable me to maintain a single set of Project Files in a single Project Group (with the obvious exception of XE2 where its Project Files don't necessarily behave very well with previous versions of Delphi due to the Platforms addition).
I suspect that I may need to put a value like $(VER) (or something similar) in the LIB suffix field, but this appears not to work and I've scoured Google looking for the correct solution.
Hope you can help!
UPDATE 1
I am now writing an IDE plugin to be used with (in the very least) Delphi 2007 to XE2, which gives DLL and BPL projects a new option called AutoSuffix. When toggled On, any IDE with the AutoSuffix plugin installed will immediately apply the correct IDE version suffix to the project.
The AutoSuffix plugin will be made available (freely) for everyone within the next 24 hours, and this question updated accordingly.
UPDATE 2
Okay... Delphi 2007 is being a pain! I've made AutoSuffix work with 2009 to XE2, so far, but 2007 requires a little more time (patience appreciated).
UPDATE 3
It would appear as though Embarcadero have heard our collective cry for simplier package unification between versions.
Mark is going to push this through to see if future versions of Delphi can accommodate a {$LIBSUFFIX AUTO} feature. I hope to hear back very soon whether this will be the case. If so, it certainly affects the way AutoSuffix will need to work on XE2 and older versions (as presently it doesn't provide the simple AUTO switch.. it has its own method).
My hope now is that EMB will take this request seriously, provide it as an integral feature going forward, so that it becomes a simple case of using AutoSuffix on existing versions to unify the process accross all versions!
AFAIK for Delphi up to XE2 there is no automatism for doing this.
Concerning the requires clause: when you require another package you are actually using the dcp, which doesn't inherit the LIBSUFFIX. Thus it is sufficient to require VCL.dcp during compile time, while VCL160.bpl is actually used during runtime. The DCP includes the complete BPL name to resolve that.
This makes the LIBSUFFIX approach superior to the simple "rename the package for each version of Delphi" one.
A solution like that suggested in QC83229 would make it easier to port a package to a newer Delphi version, but then you are still stuck with dproj files that are not backwards compatible.
I normally use different folders for each Delphi version, where only the project files are stored. For a new Delphi version I only have to copy a folder and change the LIBSUFFIX.
LIBSUFFIX directive is in *.dpk file, and you can edit *.dpk file manually.
You can write, for example
{$IFDEF CONDITIONALEXPRESSIONS}
{$IF CompilerVersion = 20.0}
{$LIBSUFFIX '120'}
{$IFEND}
{$IF CompilerVersion = 21.0}
{$LIBSUFFIX '140'}
{$IFEND}
{$ENDIF}
The bad thing is that IDE does not respect your manual edits of *.dpk file and deletes them then you make changes in a package. That is why some component vendors that use conditional defines in *.dpk file say in installation instruction if asked to save changes say 'NO'.
My suggestion would be to add this as a configurable option to project option sets (see QC #86491.) Rather than updating all the packages it would be sufficient to update a single option set file.
In fact, it seems the DllSuffix tag is recognized by the option set files in Delphi XE/XE2. Adding <DllSuffix>160</DllSuffix> to the <PropertyGroup> section of an option set file will cause the suffix to be appended to the package in the project manager. However, you still have to open the project options and click OK in order for it to be saved to the .dpk file.
I agree that it would be extremely useful with this feature (I would think also for the packages in the RTL.)
{$LIBSUFFIX AUTO} feature was added in Delphi 10.4.1:
In previous versions (version 10.3 and earlier) of C++Builder and
Delphi developers building packages needed to manually set their
package’s library suffix setting. The DocWiki “What’s new in version
10.4.1” mentions a new IDE projects option for setting the library suffix:
“Package AUTO libsuffix: packages can now have an automatic version
suffix, instead of manually updating and specifying the right version
suffix with each new release. (The compiler quietly supported this in
10.4, but full support for the feature in the IDE and package project settings is introduced in 10.4.1.)”

Delphi Compile and Build produce different binary on same project

In a fresh VCL application Compile and Build operation produce the same binary and map file (with minor differences at the end of .exe file even if "include version information in project" option is switched off - already discussed). Map file is the same byte to byte. But wen I add any third-party component the binary and map(!) file produced by Build and Compile are significantly different!
Tested on two versions of Delphi:
- Version 7.0 (Build 8.1)
- CodeGear™ RAD Studio 2007 Version 11.0.2902.10471 (+December 2007 Update)
Step to reproduce:
Create New VCL Application. Possibly add any native Delphi component (I try all components from Standart, Additional, Win32 and System tab).
Turn on Detailed Map file on Linker tab of the Project Options.
Build project.
Rename output .exe and .map file (for example: project1.exe to project1b.exe and project1.map to project1b.map).
Compile project.
Rename output .exe and .map file (for example: project1.exe to project1c.exe and project1.map to project1c.map).
Compare files from step 4 and 6. (I use WinMerge
2.12.4.0).
We have little different .exe files and fully identical .map files. Then if we repeat all steps again but use in the project third-party component (I try ODAC, DOA, DevExpress and selfmade) we get more different .exe and different .map files.
Why? Any suggestions?
UPDATE
Some information about how I found this and why it's interests me:
Project is build from simple script with MSBuild. When in the project was added translation thru ITE (dll with resources) I found that when project was Build (from script or from IDE) - translated version work wrong - some text on button, labels etc. got from wrong place (literally from another button, labels). When project Compiled from IDE - everything is ok. So I start compare Build and Compile output...
What you're seeing is simply an artifact of the built-in make logic of the compiler. When you do a build, it tells the compiler to build all available sources. So Delphi processes each source file and for each unit in the uses lists for which it finds source, it will then build that file. It does this recursively. When you do a compile, only the existing .dcu files are loaded and if they're found to be up-to-date, nothing is done. This can actually lead to a different order in which the units are discovered since each .dcu will effectively "flatten" the uses list. Since the units are discovered and loaded in a different order, they are in-turn, linked in a different order. This is why your map files look so different. Given the same sources, the map file should be the same if you do two builds in a row or two compiles in a row.
Other causes for differences are more mundane and include things like the PE header time stamp, and other bits of padding and alignments.
There is two parts to this answer I believe.
Part of the problem your seeing, IIRC, is that the compiler doesn't zero out memory before doing a compile/build. Thus anything left in uninitialized memory becomes filler in the output for alignment purposes.
I also seem to recall that there is a date time stamp included in the pe header information for the application. that will cause a difference every time.
I'm not the best person to confirm this but this is what I seem to recall from past discussions.
People like Allen Bauer or Barry Kelly would probably be able to give better/more accurate information on this.
If you use compiler defines in your project and just changed those, if you do a compile, you won't see any changes to the dcu's and the resulting module (exe or dll). If you do a full rebuild the compiler defines are used in the newly created dcu's and modules.
I have seen this in a large project group where we use modules in different projects with different defines and all dcu's are stored in the same directory.
Ergo: The compiler does not enforce the dependancies on the defines in this case.
Perhaps you did see the same issue.

How Delphi 2009 converts Delphi 7 projects re build configurations

I'm moving frequently between D7 and D2009 with library code that works with both.
For ease of going both ways, I'm routinely deleting all the D2009 additional files that get created, eg: *.dproj etc, such that on entry to D2009 I'm only ever taking D7 files.
This is nice because D2009 automatically makes a *.dproj, *.dgroup etc and apart from a notification on entry to D2009 that each project has been upgraded you can build immediately.
I have two identical machines, each with D2009 on them.
The 'good' one does what I've listed above, creating an upgraded project with the default build configurations 'base', 'debug' and 'release'. Looking in these, I can see my options copied from the Delphi 7 *.dof file (eg compilier options and output directory etc).
On the 'bad' machine with identical D7 projects supplied to it, although it 'upgrades' the projects it does not import the compiler options and output directory settings.
I've not fiddled with build configurations at all.
I can manually import a set of options saved on the good machine, but this is tedious and I'd like to find out why the 'bad' machine behaves in a different way.
Is there a 'master' build configuration that might now have a time/date that makes D2009 think I want that instead on a default upgrade?
I've just come across this exact problem.
In my Drag/Drop components, although I support Delphi 5 through Delphi 2010, I only distribute the dof files. I do this to avoid having to keep the dof and dproj files in sync. Now all of a sudden the search path setting from the dof files are not being exported to the dproj files.
The solution I've found is to strip the dof file of everything I don't need:
[FileVersion]
Version=7.0
[Directories]
OutputDir=.
UnitOutputDir=.
SearchPath=..\..\Source
With this change the dof file is imported correctly.
I haven't had time (nor reason or motivation) to investigate precisely which entry in the dof file that is preventing the SearchPath from being exported.
Ok, just a few questions, you have two machines the good the bad (and not the ugly). The good creates a valid 2009 project from the 7 project. But the bad one misses the compiler options and the directory settings.
At first, are you sure you have provided the .cfg file? This one is needed for this information.
Next, which order are the delphi versions installed. If the newest version is installed before the oldest, there can be some problems. Installing them in correct order gives no problems. (I have had 6, 7, 8, 2006, 2007, 2009 on the same machine without problems).
You said that the problems happened "suddenly". Can you recall what has been changed on the bad machine just before the problems started?
If you have the time, you can try to reïnstall anything.
Hope this helps.
Do you have relative paths in your projects? It seems that D2009 (or the BDS ide in general) reacts slightly different with respect to the work-directory used to resolve partial paths.
Sometimes when you file->open a file, all relative paths are suddenly relative to the path of that opened file. This state also seems to be more persistent.
To exclude such problem, open a file from the respective .dpr/.bdsproj/.dproj dir for each project of your projectgroup and do a build.

Automated Build scripts

How can I increment version in project files for delphi projects.I am using Delphi 10 for win32 application development. I consists of bdsproj, dpr & res files for a project.
If you are using delphi to build your application, you can turn on auto-incrementation of buildnumber under projectsettings.
We use a self made utility to generate a version resource (rc-file) based on values in a ini-file. Then we compile the rc-file into a res-file, that we include in the project.
We use finalbuilder-scripts to automate the process. I know finalbuilder has its own support for versionnumbers, but we don't use it. I don't know why, though...
I previously used a program called StampVer, You will need to already have version information in the file to use StampVer. StampVer is Freeware but not Open Source.
The nice thing about stampver, is that it can auto-increment for you.
I use a proper build script tool FinalBuilder which has a set of property management commands which can set all items in a build to the same version. This gives me consistency of numbering across a build, and a whole load more too. If you don't have a proper build tool, and are still using batch files or equivalent, now is a good time to go look at the options. Well worth doing.
I use a program that manages the version number in a .ini file and generates a .res file in the pre-build event of the project. This .res file contains only the version, not the icon. The icon is contained in a separate .res file. Both are being included in the project's dpr file:
{$R *_version.res}
{$R *_icon.res}
Only the *__i_con.res file gets checked into source conntrol, the version, as said above is maintained in an .ini file, so the *_version.res file can be generated whenever necessary. This gets rid of the annoyance of the .res and .dproj file constantly changing due to incrementing the build number.
Oh, I just realized that you said "Delphi 10", which I think is Delphi 2006. That Delphi version did not have pre- and post-build events, so you would have to call the program for maintaining the version yourself.
Read this article http://www.thedelphigeek.com/2008/01/tdm-rerun-2-better-build-process.html
by Primoz Gabrijelcic, originally published in The Delphi Magazine. It contains a complete description on what you need to do.
If you are looking for a non-gui way of doing this then I think if you look in the bdsproj file you will find a section in the xml where the version is written you can change it here. The next time it builds it will use this version.
DDevExtensions has a build incrementer in it, I'm not sure how to get the delphi 2006 version, but I think it exists and it's pretty handy stuff.
Do you need to increment the build number when you compile from the IDE, or outside? The IDE can increment it automatically, just check the flag in the project settings.
Incrementing that number outside the IDE is not simple because it is stored in the default .res file which is managed and regenerated by the IDE.
The command line compiler will not modify it. There are several ways to modify it (as other answer explain), and usually it works best with a build system that can generate the build numbers, especially if more than one developers work on the project.
I posted QC #70564 issue to ask that version info can be set by the command line compiler.

Resources