29 June, 2012

Different EurekaLog settings for 'Debug' and 'Release' profiles

This article is supposed to answer on one common question asked by our customers. They want to use different EurekaLog settings for different compilation profiles. Sometimes even no use EurekaLog at all for some specific profile.

This article will explain how to do this.

Important Note: please see most recent version of this documentation here.

Well, first - unfortunately, there is no IDE solution for certain technical reasons. But this doesn't mean that you can't do this. You can't use automatic solution, but you can perfectly set all options manually.

For the purposes of this article I will use EurekaLog 7.0.1 and Delphi XE. The discussed features may be unavailable in older versions.

Step 1: get working solution for single profile

First, I created a new VCL application and place a button to raise exception. Then I go to Project/EurekaLog options, enabled EurekaLog and specified type of my application (VCL Forms). You can also set other options as you desire. Now run the application and confirm it's working as expected.

Step 2: reconfigure project for manual control

For the next step you should go to Project/EurekaLog options and use "Export" button to create .eof file. Place it in the same folder as your project (by default "Profiles" folder is suggested). Name it as your project + name of your configuration. For example: Project1_Debug.eof.

Now, don't close options dialog, but go to Advanced/Custom/Manual and add "DoNotTouch=1" line (without quotes) in any place (as new line). This will disable any assist for your project from IDE expert. Close settings and save your project.

You can confirm if option is taking effect by disabling EurekaLog, saving your project and observing that there are no changes in your .dpr file - all units are still included even if no EurekaLog is enabled.

Now, it's time to restore post-processing for your application. Go to Project/Options (not EurekaLog options) and look for build events options. Add the following command as post-build event which is invoked on successful compilation:
IF EXIST "$(BDS)\Bin\ecc32.exe" "$(BDS)\Bin\ecc32.exe" --el_alter_exe"$(PROJECTPATH);$(OUTPUTPATH)" --el_config"Project1_$(Config).eof"
Replace "Project1" with your real project name or change the whole argument to match your .eof file.

The $(Config) is a variable, which will be substituted with the name of build configuration - such as "Debug" or "Release" or any other custom configuration name. So, the resulting command-line may look like this when run:
IF EXIST "C:\Program Files (x86)\Embarcadero\RAD Studio\8.0\Bin\ecc32.exe" "C:\Program Files (x86)\Embarcadero\RAD Studio\8.0\Bin\ecc32.exe" --el_alter_exe"C:\Projects\Project1.dproj;C:\Projects\Debug\Win32\Project1.exe" --el_config"Project1_Debug.eof"
Note that this is an example of final command as it will be executed by IDE. You should NOT use this form of command (with already expanded variables) - please use the first example with $(Config) variable.

Note: you can also find the $(Platform) variable useful. It will be replaced with short name of the platform - such as Win32, Win64, OSX. So you can have file like Project1_Win32_Debug.eof and use --el_config"Project1_$(Platform)_$(Config).eof switch.

Now compile your project and run it. If you done everything correctly - the result must be the same as on step 1 - the correct EurekaLog-enabled application with expected behavior as set in external .eof file (even though the EurekaLog was disabled in project).

In case of any build errors - take a look at compiler output as shown in "Messages" window. It's docked at the bottom of IDE window by default. "Output" tab is near "Build" tab, which is active by default. If you don't see "Messages" window - use View/Messages command to show it, then switch to output window. The correct compilation will get you such messages:
Build started 2012.06.29 16:58:04.
__________________________________________________
Project "C:\Projects\Project1.dproj" (Build target(s)):
Target _PasCoreCompile:
    C:\program files (x86)\embarcadero\rad studio\8.0\bin\dcc32.exe //-- options cut to save space --// Project1.dpr   
Target PostBuildEvent:
    IF EXIST "C:\program files (x86)\embarcadero\rad studio\8.0\Bin\ecc32.exe" "C:\program files (x86)\embarcadero\rad studio\8.0\Bin\ecc32.exe" --el_alter_exe"C:\Projects\Project1.dproj;.\Debug\Win32\Project1.exe" --el_config"Project1_Debug.eof"
    EurekaLog Command-Line Compiler v7.0.1.0 for Delphi 15.0
    ----------------------------------------------------------------
    
    Loading EurekaLog options...
    EurekaLog postprocessor start...
    EurekaLog's code was added
    EurekaLog's options were added
    EurekaLog's data was added
      File size before:     2'159'616
      File size after:      2'185'216
      File size diff:       +25'600
      Debug info size:      287'554
      Symbols size:         58
      Functions size:       4
      Stripped size:        -138'240
      Number of units:      209
      Number of procedures: 10'136
      Number of lines:      28'124
      Total time:           00:00:00.639
        Compilation time:   00:00:00.026
        Prepare time:       00:00:00.015
        Post-process time:  00:00:00.597
        Events time:        00:00:00.001
      Memory usage:
        Allocated:          7'576'806
        RAM:                29'999'104
        Private:            27'066'368
        Virtual:            105'299'968
    EurekaLog postprocessor end
Build succeeded.
    0 Warning(s)
    0 Error(s)
Time Elapsed 00:00:01.91

Step 3: configuring alternative profiles

Now it's time to set up configuration of alternative profiles (finally). The first thing you need to do - is to decide if you want EurekaLog for this configuration or not. The difference is that you need different project options set for different cases. As well as different unit set.

Let's do this one step at time.

First, conditional directives. They are not used by EurekaLog, but it will come in handy for your own purposes. So, go to Project/Options and look to Delphi Compiler/Conditional Defines option. Now, if you want EurekaLog for this profile - add "EL" conditional define. If you don't want EurekaLog for this profile - remove EL conditional define. The name of symbol is any text. You can use other name instead of EL. Repeat this step for each profile of your project that you're going to use.

Note: currently 7.0.1 removes conditional define with name of "EUREKALOG". I think this should be fixed in the next minor update.

Second, the options of the project. EurekaLog requires certain options to be set in order to work. Also, some option may increase or decrease detalization of EurekaLog. So, if you want to use EurekaLog in certain profile - then you have to setup all required options manually. Please, read this article to know what options must be set. For other profiles (in which EurekaLog will not be used) you can set options as you desire, there are no limitations.

Third, the included units. Use Project/View source command to open your .dpr file in code editor. You should see EurekaLog units included. If you don't want EurekaLog for certain configurations - then you (probably) don't need to include EurekaLog code. So, you can make this like this:
program Project1;

uses
  {$IFDEF EL}
  EMemLeaks,
  EResLeaks,
  EDialogWinAPIMSClassic,
  EDialogWinAPIEurekaLogDetailed,
  EDialogWinAPIStepsToReproduce,
  EDebugExports,
  EDebugJCL,
  EAppVCL,
  ExceptionLog7,
  {$ENDIF}
  Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
Please note that exact included units depends on your selected options. For example, if you set error dialog to "None" - then EDialogXYZ units may be removed. So if you change original options - you may have to include/remove units manually. If you are not very well familiar with EurekaLog 7 - I recommend to create a new application for testing. Setup EurekaLog options and see which unit will be included.

Note: you can skip steps 1 and 3 if you want EurekaLog to be enabled for each profile (just with different settings).

Note: you can also use EBase unit to test whenever EurekaLog was enabled for your application or not. This unit is specially designed to be included in any application without including EurekaLog's code.

Fourth, you have to create .eof file for each configuration profile and save it with corresponding name (such as Project1_Release.eof in our example, but you may use any other naming scheme). Be aware that you also need to create .eof file for profiles with disabled EurekaLog! You need to disable EurekaLog in such .eof files. You can use IDE options dialog: use Import/Export buttons to open/save settings. Or you can use standalone settings editor tool (you can add it to Tools menu for quick access).

Note: the result of using IDE expert and settings editor tool is a bit different. IDE expert only saves settings which are different from defaults. Settings editor saves all options.

At last - make sure that post-build event that we set in options at previous step is applied for all profiles (you can do this by entering command to Base profile and checking that it wasn't overwritten by another profiles).

Now, do a test - switch to different configuration profiles, make a build, run application and test it.

Note: it's recommended to make a full rebuild when changing profiles or target platform.

Conclusion

This article explained the basics of manual control over configuration of your project. I really hope that it's not that hard and that it answers many questions.

As a side note - I want to discuss relation between settings and configuration profile names. In classic application: the debug profile has maximum debug options set, and the release profile has minimum debug options set. For applications with exceptions tracers it's different. Exception tracer requires more info than you usually use for debugging sessions (think about "Use Debug DCUs" option). So typically it's reversed now: you want maximum options for release version of your application and medium (moderate) options for debugging. Therefore, you can either swap profiles (i.e. use "debug" profile for the release version of your application) or to completely re-setup options between profiles.