Conditional compilation

From Free Pascal wiki
Jump to navigationJump to search

Compile-Time Defines {$DEFINE}

Why?

If you have an application that needs several variations - say for two customers, or for two operating systems then compile-time defines are just what you need. For a practical example see: http://wiki.freepascal.org/Code_Conversion_Guide#Useful_compiler_variables_.2F_defines_.2F_macros

How?

There are three ways to do this. 1) Unit based {$DEFINE} and {$IFDEF} statements 2) Include file 3) 2) Project | Project Options | Compiler Options | Other | Custom options

Commands

Nested $IFNDEF, $IFDEF, $ENDIF, $ELSE, $DEFINE, $UNDEF are allowed

In Custom options -d is the same as #DEFINE -u is the same as #UNDEF

Examples

1) and 2) must be done individually for each unit. 3) An entry applies to every unit

1) Unit based {$DEFINE} and {$IFDEF} statements

Create a single form project as below. Comment and uncomment the two {$DEFINE) statements in turn and see what happens. If you add a second form (Form2) which opens when the first form (Form1) is clicked, similar statements will work independently of the {$DEFINE} statements in Form1.

var

 Form1: TForm1;

implementation

{$R *.lfm} {$DEFINE RED} //{$DEFINE BLUE} { TForm1 }

procedure TForm1.FormClick(Sender: TObject); begin

 {$IFDEF RED} Form1.Color := clRed; {$ENDIF}
 {$IFDEF BLUE} Form1.Color := clBlue; {$ENDIF}
 {$IFDEF BLUE AND $IFDEF RED} Form1.Color := clYellow; {$ENDIF}
 {$IFNDEF RED AND $IFNDEF BLUE} Form1.Color := clAqua; {$ENDIF}

end;

Include files

Include files add code into any .pas unit.

Create a file called unit1.inc (It could be called anything.inc.) that contains:

{$DEFINE RED} //{$DEFINE BLUE}

Create another called unit1a.inc that contains:

 {$IFDEF RED} Form1.Color := clRed; {$ENDIF}
 {$IFDEF BLUE} Form1.Color := clBlue; {$ENDIF}
 {$IFDEF BLUE AND $IFDEF RED} Form1.Color := clYellow; {$ENDIF}
 {$IFNDEF RED AND $IFNDEF BLUE} Form1.Color := clAqua; {$ENDIF}

Add them to the project folder. When compiled, these lines will replace the $INCLUDE statements below. Both methods present the same code to the compiler. However, using the include file method makes it easier to handle more complex requirements.

var

 Form1: TForm1;

implementation

{$R *.lfm}

 {$INCLUDE unit1.inc}

{ TForm1 }

procedure TForm1.FormClick(Sender: TObject); begin

 {$INCLUDE unit1a.inc}

end;

Project | Project Options | Compiler Options | Other | Custom options

Comment out the {$DEFINE} statements and add the directives as below. In this case the directives will apply to all units. Note the -d prefix. -dRED -dBLUE

Updates to follow. Windsurferme 26/10/2013