Difference between revisions of "Conditional compilation"

From Free Pascal wiki
Jump to navigationJump to search
Line 24: Line 24:
 
1) and 2) must be done individually for each unit. 3) An entry applies to every unit
 
1) and 2) must be done individually for each unit. 3) An entry applies to every unit
  
==== Unit based {$DEFINE} and {$IFDEF} statements ====
+
#==== 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.
 
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.
  

Revision as of 23:53, 26 September 2013

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