1. Computing

Have Two Applications In One Delphi Program (Conditional Compilation) - Part 1

Conditional Compilation 101: Project Group, Project, Program: Debug or Release?

By

Have Two Applications In One Delphi Program (Conditional Compilation) - Part 1
Delphi Project Manager
When creating "normal" Delphi desktop applications (not services or web servers and similar), let's say using the VCL, you would start by selecting "New VCL Forms Application" from the IDE's main menu. This will create a program/application skeleton for you containing a single form. You add more forms and units to build your application.

Project Group, Project, Program, Application

Now, the above action will actually create a new "project". Take a look at the Project Manager (somewhere in the IDE or make it visible by selecting View-Project Manager from the IDE's main menu). You'll see "ProjectX" (containing UnitX.pas) that is a part of what is called "ProjectGroupX". The X can be "1" or "2" or similar, depending on how many projects (sorry, applications) you started and saved, but did not change the default name.

Therefore, the newly created "application" is actually a "project" in some project group.

A complete, Delphi executable application consists of multiple units, all tied together by a single source code unit called a project file (like the One Ring).

If you take a look at the projects file source code (DPR), you'll note the DPR unit starts with the reserved word "program".

The program keyword, inside the DPR source file, identifies this unit as a program's main source unit. You can see that the unit name, ProjectX, follows the program keyword (Delphi gives the project a default name until you save the project with a more meaningful name). When you compile (or build) Delphi uses the name of the project file for the name of the EXE file that it creates.

Again, normally, all the forms and units that are part of the project would be compiled/linked into the final executable file.

For the sake of this article, and since in developers talking both "program" and "application" are used to describe the same thing, I will refer to "program" when I think of a project, and the "application" will be the final executable.

Ok, all set and we can continue with the article main idea :)

Two Applications In One Project (sorry, Program)

Have you even wanted to have two executable versions for your application? Let's say one "trial" and one "normal"?

Have you ever needed to include or not include pieces (some forms, units) of the project based on some criteria?

Have you ever needed to have the same code base in one program but also have an option to build two (or more) different applications?

If the answer to any of the above is "yes", then you are ready to learn about Delphi's conditional compilation.

Conditional Compilation

Now, before moving into a discussion how to have "here's how" for the above (and similar questions) let's see what conditional compilation is.

Delphi component developers are certainly familiar with conditional compilation.

However, if you plan on writing Delphi code that should work with several version of the Delphi compiler (as you are working in a team and not all members are using the same Delphi version, for a dummy example) you need to know under which versions your code gets compiled.

The Delphi Compiler Version Directives article has some startup info on how conditional compilation is used to test the version of the Delphi compiler.

Essentially, conditional compilation is based on the existence and evaluation of constants, the status of compiler switches, and the definition of conditional symbols. Such symbols are like boolean values.

There's a set of pre-defined conditional symbols in Delphi like: "MSWINDOWS" (indicates that the operating environment is Windows), "CONSOLE" (defined if an application is being compiled as a console application), "WIN32" (use to distinguish between specific Windows platforms, such as 32-bit versus 64-bit) and alike (above mentioned VER symbols to indicate the compiler version).

As stated, conditional symbols act like boolean values, they are either defined (true) or undefined (false). Any conditional symbol is treated as false until it has been defined.

Since conditional symbols are like boolean values, to test for true or false, you would use the "special version" of the if then else statement.

Here's an example:

{$IFDEF DEBUG}
  Caption := '"DEBUG" is defined and "on"';
{$ELSE}
  Caption := '"DEBUG" is not defined and "off"';
{$ENDIF}

Try placing the above code inside the OnCreate event handler for the (main) form of the application (program, project) created at the beginning of the article.

Now, take a look at the Project Manager, the "Build Configurations" node. Either "Debug" or "Release" will be bold. That is the currently active build configurations. Double click one to activate it. Run (F9) the application. Note the different form caption depending on what the active build configuration is? Ha! Conditional compilation in action!!

IFDEF, IFNDEF

Just like normal if and else, the "$IFDEF" and "$IFNDEF" along with "$ELSE" and "$ENDIF" are used when you want to leverage conditional compilation. They get surrounded by "{" and "}".

The "IFDEF" means "if defined" whatever comes after it. IFNDEF is for "not defined". In the above example the conditional symbol is "DEBUG" - a pre-defined symbol by Delphi used in "debug build configuration".

You cannot use conditional symbols with normal if/then/else statements.

Now, the question comes up: how do I define my own conditional symbols? How do I go with:

{$IFDEF MY_CONDITIONAL_SYMBOL}
  Caption := 'This is a TRIAL version, buy the full one to have all the features!"';
{$ENDIF}
First, note that when a conditional symbol, like "MY_CONDITIONAL_SYMBOL", is NOT defined the above would always evaluate to false and the "Caption := ..." line of code would never execute.

For all the answer to the raised questions in this article, continue reading: Two Applications In One Delphi Program (Using Conditional Compilation) - Part 2.

©2014 About.com. All rights reserved.