3

In my Delphi, whenever I rebuild my application, all 3rd party component's DCU files are getting generated in my application's directory, where the executable resides.
How do I change this behaviour?
So that third party component's DCU files won't get generated in my application directory.

Johan
  • 74,508
  • 24
  • 191
  • 319
jimsweb
  • 1,082
  • 2
  • 17
  • 37
  • 4
    You can define the output directory for *all* DCU's via Project/Options/Delphi-Compiler/Unit output directory – bummi Sep 22 '13 at 10:23
  • 2
    I'm not quite sure Bummi or David completely answered your question. As I understand it, you want to put 3rd party component DCUs in one folder, and *your* DCUs in another. I think there's a way you can manually copy the 3rd party DCUs to a 2nd folder and then have the compiler search that folder first. (You may have to hide the 3rd party DCUs source folder from the compiler (using Options) so they don't get re-created when building.) In case this was your need, I thought I'd mention it so someone else than me who knows the details can post them. – RobertFrank Sep 22 '13 at 13:34
  • It seems to me that the practices in this area vary widely from one company and developer to the next. – Warren P Sep 23 '13 at 19:18

2 Answers2

7

The .dcu files that the compiler generates are all created in the same directory. So there's no way to put generated .dcu files files into different directories and separate those from third party libraries from those from your source files.

However, it's generally a bad idea to put the .dcu files into the same directory as the source files. That just clutters things up. Best practise is to put the .dcu files into a sub-directory of your project. The compiler options let you do this. Open up the compiler options dialog and change the target drop down to All configurations - All platforms. This is the base configuration that you other configurations inherit from. The dialog looks like this:

enter image description here

The setting you need to change is Unit output directory. The image above shows the default for a new project on XE2. The value .\$(Platform)\$(Config) is expanded by the compiler. So if you are building a debug config targeting the Win32 platform, your .dcu files will be output to .\Win32\Debug.

The compiler options are documented here: http://docwiki.embarcadero.com/RADStudio/en/Delphi_Compiler

The description of the unit output directory is:

Specifies a separate directory to contain the .dcu.

The other closely related option is the output directory. This is where the compiled executable file will be placed. If you are targeting multiple platforms then you really need to put this executable file somewhere other than the main project directory. Otherwise automating build becomes difficult and error prone. It's all too easy to pick up an out of date 32 bit executable when you actually want a 64 bit executable.

So my advice to you is to use the default of .\$(Platform)\$(Config) since it is an excellent default.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
1

I generally make a COMP\ folder in my source repository, which I will show as a folder tree here:

    root
      |
      comp\
      | |
      | |--  TMS\   - TMS component set
      | |
      | |--  JEDI\  - Jedi VCL and JCL
      | |
      | |--  Something\ - Your other favorite component
      |
      app\    - My application source code.

Under the comp\ folder I create the following other DCU folders:

    comp\
      |
      LIB\
        |
        DXE4\

All my component packages (.dpk + .dproj) are modified to build and output into the comp\LIB\xxx folder, where xxx is a short code that refers to a specific delphi version.

Then from my delphi root\App\MyApp1 folder, I have a APP\DCU\DXE4 folder, which is where the DCU files go for my main application project App.dproj. The Project Search Path for App.Dproj pulls in the already-compiled DCU, DFM and RES files which are found in comp\LIB\DXE4. This means that the App\ projects do NOT rebuild my components from their source code files. This speeds up compilation.

As David points out, each project has only one DCU OUTPUT folder which is specified. So that folder which is the DCU OUTPUT folder for my component .dpk package compilation becomes a library INPUT folder, during my application (.dpr+.dproj) compile stage.

Because I need to make both .dfm, .res, and .dcu files available in the COMP\LIB\DXE4 folder, I have a batch file (buildcomp.cmd) which does all builds, and copies necessary to make the LIB\DXE4 folder contain all it must contain. I do NOT check the contents of the LIB... folders into my version control system. They are binary and output products of my Component Build stage. Keeping the Component Build stage and the Application Build completely separate is a more scalable approach for larger applications and larger sets of components.

I choose to keep the BPL and DCP files in their default location (under %(BDSCOMMONDIR)\BPL) but some people choose to redirect their BPL and DCP files into their COMP\LIB\DXE4 equivalent folder. There is no uniform standard behaviour among Delphi developers, each developer or company seems to do what works for them. The bog standard Delphi practice is to ignore such practices completely and be as disorganized as possible, so the fact that you have started to even ask such a question speaks to the praiseworthy tendency you have to notice that there is some disorder that you may wish to impose some structure of some kind upon, if it benefits you or your company.

Warren P
  • 65,725
  • 40
  • 181
  • 316
  • Surely, you would use runtime packages, or include the files in your project. But it sounds like you are doing both. Why? – David Heffernan Sep 22 '13 at 17:24
  • Some people may choose to use Runtime Packages and in that case then they have a potential for DLL-hell in their piecewise application. Remember that Delphi lacks a true "library" (.LIB) file format, and so a folder full of "LIB\DCUXE4\*.dcu" files is the closest you can get to library-style workflow (where component code is not recompiled at each rebuild of your application). If you wish to recompile all your component code and your application code at the same time, in your small Delphi applications, you can. However the larger your app grows the less desirable this becomes. – Warren P Sep 23 '13 at 18:21
  • The BPL files I build are for the IDE's benefit, not for my application's benefit. That is, BPLs are the only only way to load stuff into the IDE (ie, components) but they are optional for application developers. In my case, I wish to build and link statically, a monolithic executable, and I also need to install BPLs into the IDE. Thus I need both. – Warren P Sep 23 '13 at 18:22
  • Define large. You should be able to compiler around 1M loc Delphi projects in 10s. More if you target 64 bit. Also, with incremental builds, you don't recompile the libraries apart from complete builds. – David Heffernan Sep 23 '13 at 18:26
  • Our apps not only are > 1.5 MLOC, they are also composed of code that requires compilation with different global compiler parameters (for historical reasons). So we're really really interested in a Precompiled DCU Library for our components. – Warren P Sep 23 '13 at 19:16
  • Incremental build should handle that fine. Perhaps I don't understand. – David Heffernan Sep 23 '13 at 19:25
  • Imagine you have 1.5 MLOC of code in 5500+ units, and 800 of those are yours, and the others are third party components. Now imagine that you need different compiler settings for various subsets of those files. Now try to build them all in one .dproj. In the C/C++ world you would be using libraries. – Warren P Sep 24 '13 at 00:52