I have to maintain old software written in Delphi. The source tree is a real mess. I'm trying to do 2 things: to make clean directory structure and to set up automated build process.
Right now i have produced following directory tree
\Project \build\output \dist\release \dist\debug \doc \env \res \src
\src
directory contains *.pas
and *.dfm
files and project.dpr
. Various resources (icons, images and fonts) are reside in \res
directory. \env
is used to create various environments for debugging purposes. IDE was setted up to build project.exe into this dir.
Build scripts are stored in build
folder. These scripts produce product distribution (with and without debug information in exe) in dist\release
and dist\debug
folders with help of dcc32.exe
. build\output
is used to save dcu files during build process inside IDE or inside build script.
There is a little flaw in my approach. I can not start with fresh computer, checkout code from my repo, start building script and receive ready to use disitribution of the project. I need to open IDE first, install required components (e.g. RXLib
and MemoEx
), set up library paths and so on. Only after that steps i can run my building scripts.
It was not a big problem until last week. I've modified 3rd party component in order to fix a bug (this component isn't maintained anymore :-(), so i have to add code of this component to the structure of my project. At this point if i will checkout from the repo I need to check if there were changes in code of 3rd party libs. If code of libs was changed I need to recompile components and reinstall them.
Questions
bpl
and dcu
which will be produced during build of components. Should i place them at Project\build\output
? Or it will be better to place output to another location (do not override Delphi settings), but change Library path in project configuration?You just have to compile the package with the delphi commandline compiler. If the Delphi bin path is in your PATH
you don't have to hard code the installtion path. If your build system is able to read from the registry you get the path e.g. HKEY_LOCAL_MACHINE\SOFTWARE\CodeGear\BDS\6.0\RootDir
(Delphi 2009 in this case).
I would add another branch components
with subbranches for every package. Do not mix them with your projects.
From my experience the best practive is to keep them in the delphi destination (where depends on the delphi version).
Update: Noticed the Install from command line Request part of the question.
You can't really install from the command line but it would be easy to build something that did that. You can compile the packages using DCC32.EXE.
The installation of components is controlled by registry entries. The location in the registry is different for each version of Delphi, but it does follow the same basic pattern. Examples:
Delphi 2007
HKEY_CURRENT_USER\Software\Borland\BDS\5.0\Known Packages
Delphi XE
'HKEY_CURRENT_USER\Software\Embarcadero\BDS\8.0\Known Packages'
We update this using FinalBuilder, after we have build all the 3rd party components. It makes it easier to keep each developer in sync.
As for directory structure, I think about version control up front and do the following.
Root Directory...
C:\dev\trunk\
This allows me to create branches in an easy format.
C:\dev\branch1\
From there I do the following:
I use a common directory for \Bin and \DCU since I do a lot of package development many of which need to be loaded at design time. This prevents having to add many directories to the system path to keep Delphi happy.
\output\DelphiXE\Bin
\output\DelphiXE\Dcu
This can be enhanced if need to be like this:
\output\DelphiXE\Release\Bin
\output\DelphiXE\Release\Dcu
\output\DelphiXE\Debug\Bin
\output\DelphiXE\Debug\Dcu
The for each project, I do this, although often I place more than one project in the same directory if the rely on the majority of the same code.
\project\ (DPR/DPK Here)
\project\source (if the project is small, if not I break it out further)
\project\forms\
\project\classes\
\project\datamodules\
\project\resources\
\project\install\ (Install Scripts)
etc...
The finally for components and code common to different projects.
\Commonlib\ (Directory for my code that common among projects)
\Components\3rdPartyName\
\Components\3rdPartyName2\
\Components\3rdPartyName3\
I do it this way so I know every thing made up my version X of my application by just using the version control revision number.
To top this off I create an environment variable for
C:\DEV\TRUNK\
Then I use the environment variable in the system library path. Like this:
%MYCODE%components\3rdParty1;%MYCODE%components\3rdParty2\
Then if I have to switch branches I can change the environment variable relaunch Delphi and everything using that version of the code base.
1: Yes and no, you can design your own components to be installed from the command line (where "from the command line" means install them programatically, if you really want command line, you might need to write the tool). 3rd party components usually come with an installer that does more then install and register the components themselves. Theoretically you can automate everything the installer does and essentially repackage the component for your own use, but you might run into legal barriers doing this.
2: 3rd party components aren't tied to a project. Storing those files in the project directory is not a good idea. What happens when you reuse the same components in an other project? Do you copy all source files to the new project? For my own work I've got all 3rd party components installed into one folder, separate from any project's directory, and I keep that folder under version control.
3: Using a separate output directory for each project is a good idea, it makes using conditional compilation much easier. I'd suggest separate output directories for Debug and Release. About 3rd party BPL's, they're also not part of the project because no single project "owns them".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With