Conditional Compiler Options

From Lazarus wiki
Jump to navigationJump to search

This page collects ideas of how to implement conditional compiler options in lazarus.

First it should be collected the cases, where conditional compiler options are needed.

Case studies

Conditional Package Requirement: VirtualTreeView / multilog

Make it possible to define a package requirement as optional (Should be available both to package and program). Concrete situation: VirtualTreeView requires multilog package to help debug code. In a release it is not desired to have such dependency. Currently there are two possibilities:

  • in the release remove the dependency from the package, and then add again to reenable debugging.
  • enclose the units of the package with {$IFNDEF MYRELEASE} and add -dMYRELEASE to the project and all package compiler options (or fpc.cfg).

An idea is to have groups of conditional requirements. Each group would have a define value associated to be used at compile time (e.g: 'DEBUG_CODE') and child packages. Each group would have an enabled flag. If group is enabled, the child packages are added as requirements and the define value passed with -d to the compiler.

  • Disadvantage: Other packages will use the same Debug/Release differences. In big projects normally only a small part should be set verbose (into debugging mode).

Target specific units

Make units packages/projects optional according to OS. Concrete situation: LCL extensions package has a unit (OleUtils) that implements TOLEStream. It only makes sense in Windows. Currently the unit is added in all widgetsets but all code is wrapped around a ifdef Windows define so is seen as a dummy unit in other widgetsets.


  • All units should be added to the package, independent if they are used. If a unit should not always be compiled in (not added to the uses section of the package), just unset the 'uses unit' checkbox.
    • If the "uses unit" flag is not set, the unit will not be compiled. Nor in win32 (where is needed) neither in the other OS-es. It will be compiled only if another unit in the package uses it. So you must add for example {$IFDEF win32}uses oleutils.pas{$ENDIF} somewhere to one of the package units.
  • You can put units specific to targets into sub directories as demonstrated in the Lazarus and FPC sources (units/$(TargetOS)).
    • OK. But how to make this unit compile when compiled in TargetOS (in this case windows)?. The package only compiles the units that belongs to it (the units show in the package dialog).
  • Conclusion: There is no real need for conditional options for single units, as this is already possible.

Special build modes

Any application will desire different options for at least 2 possibilities:

  • Debug - which should be default
  • Release

So, any application should already come with those 2 options, and legacy applications could have them added automatically.

To have a trully flexible system any number of compilation modes should be supported (maybe >= 1 to have at least one). One idea to implement this system would be having any mode use all options set on the dialog, but also have a list of which options it will override to a custom value.

An extra idea is having the build options available on the Project -> Build menu

We could have: Project -> Build mode -> Debug; Release; Etc (submenu with all build modes), like Xcode has.

Arbitrary number of build modes - Virtual Magnifying Glass

One case where an arbitrary number of build modes would be excelent is the Virtual Magnifying Glass. Because Mac OS X requires special build options which can't be used on other operating systems, the magnifier could have the following options:

  • Debug
  • Release
  • Mac Qt4 Debug
  • Mac Qt4 Release
  • Mac Carbon Debug
  • Mac Carbon Release

The Mac Qt4 options need to add "-framework Qt4Intf -lobjc" to the extra linker options and active the extra linker options.

The Mac Carbon options need to add "-framework carbon" to the extra linker options and active the extra linker options.

LCL Widgetsets

At the moment the LCL widgetsets are hardwired. It would be great if these could be done by the conditionals, because

  • If it can handle such a complex beast like the LCL it can handle almost anything
  • The conditionals will be well supported

For this is needed:

  • define a flag (LCLWidgetSet) with a list of values (gtk, gtk2, ...) and names. This flag must be usable as macro. The macro can be used in paths and descendant package paths.
  • Somehow a default must be defined depending on target platform.
  • conditional codetools defines. This could be achieved by a dialog or extra compiler options page like the codetools defines editor. This may be used for the FPC source packages too.
    • Advantage: Full control and very flexible
    • Disadvantage: Only very few packages need this flexibility. Most conditional packages only need two modes like release/debug. For these simple cases more intuitive frontends could be created. The problem is, that the simple frontends can not show the complex setups correctly.
  • paths (linker, custom options) must be conditional
  • All such flags of all packages used by the project should be collected and the user must be able to easily switch the flags.