Macros and Conditionals

From Lazarus wiki
Revision as of 16:23, 30 September 2010 by Mattias2 (talk | contribs)
Jump to navigationJump to search

Overview

Macros can be used in search paths and file names to let the IDE automatically adapt them to the target platform. Build macros are project/package specific macros. A prominent example is the LCLWidgetType, which is defined by the package LCL and allows to choose the widget set (carbon, gtk, qt, win32, wince, ...).

Conditionals allow to set macros depending on the target platform and/or other macros. For example you can use them to define special linker options when compiling for Mac OS X. They use a pascal like scripting language allowing to define even complex rules.

You can set the build macros and conditionals for a package via package editor / Compiler Options / Build Macros.

You can set the build macros and conditionals for a project via Project / Project Options / Compiler Options / Build Macros.

Build macros and conditionals exist since Lazarus 0.9.29.

Build Macros

A build macro has a name and a set of possible values.

Macro names

The name must be a valid pascal identifier and is case insensitive. For package macros it is recommended to prefix the macro name with the package name plus the underscore. For example a package named Pkg1 can have a macro named Pkg1_Macro1. When the package is renamed the IDE will automatically rename the macros too. It is allowed to define macros without the prefix, but keep in mind that this can lead easily to conflicts and misunderstandings. For example if you name a macro 'debug', 'release' or 'verbose' chances are high that some project defines a macro with the same name.

Possible macro values

You can and should define the set of possible values. These values are a clue for the users of your package. The user is free to set any other value, even empty or undefined. The list of values is shown in the comboxbox on the Build Modes page of the project's compiler options.

Scope

When the project defines the value of a macro via the build modes page, this value is visible to the project and all packages. The value is used when parsing conditionals and conditionals can not override them.

A macro value defined by the project's conditionals is only visible to the project's search paths and file names.

A macro value defined by the package's conditionals is only visible to the package's search paths and file names. Conditionals can set the build macro of the package and can alter the usage options of the package. See the examples below.

Conditionals

The conditionals use a simple scripting language. Here are some short examples:

Adding a compiler flag for target Linux

<Delphi> if TargetOS = 'linux' then

 CustomOptions := '-dUseCThreads';

</Delphi>

Note:

  • TargetOS is a predefined macro by the IDE.
  • CustomOptions is a result variable used by the IDE.
  • The identifiers are case insensitive, but = (equal) operator is not. The TargetOS macro uses the same case as the compiler does, which is currently all lowercase.
  • The IDE adds the first space automatically when adding the custom options.

Adding some linker option for target Mac OS X

The compiler uses for Mac OS X the value 'darwin' for TargetOS.

<Delphi> if TargetOS = 'darwin' then begin

 LinkerOptions += ' -k-framework -kCocoa';
 if TargetCPU = 'i386' then 
   LinkerOptions += ' -k-framework -kOpenGL';

end; </Delphi>

Notes:

  • TargetOS and TargetCPU are predefined macros by the IDE.
  • The += operator appends a string or adds a number.
  • When adding several options you have to add a space between options.
  • The IDE adds the first space automatically when adding the linker options.
  • You can nest begin..end just like Pascal.
  • If both conditions hold LinkerOptions will contain the value ' -k-framework -kCocoa -k-framework -kOpenGL'.