Search code examples
delphicomponentsbuild-automationproject-structuring

Project directory structure with 3rd party components


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

  1. Is there any way to reinstall components in Delphi 7 from command line? Is there any way to do it without hardcoding installation path of D7?
  2. How would you store code of third part components in project tree?
  3. Where should i place 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?

Solution

  • 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.