Chapter 3. Bakefile Concepts

Table of Contents

Targets
Variables
Templates
Options
Conditions
Conditional Variables
Modules
Presets
Paths

Targets

Like in traditional makefiles. Target is a single buildable entity, e.g. executable, library or DLL. See Chapter 4, Targets for details.

Variables

You can set and use variables in Bakefile in a way very similar to other make programs. Variables may be either global or local to the target they are bound to. Note that variables are expanded by Bakefile and do not appear as variables in generated native makefiles (compare with options).

Variables are expanded by typing $(var) (for some variable var) in makefile text. Same syntax is used to expand options and conditional variables, too.

Templates

It is often the case that several targets in the makefile share the same properties: for example, they are installed into same directory, use same compiler settings or include headers from same directories. Templates are a mechanism designed to eliminate such duplication from makefiles. In Bakefile, you simply declare that a target derives from template (or templates) and it will inherit all its properties. See description of template command.

Options

It is desirable that generated makefiles are configurable to some degree (especially with the autoconf backend). Bakefile makes it possible to declare so-called options using option command. Each format backend has its own way of presenting options and some formats may fail to support them at all. Some formats (such as Visual C++ project files backend) have only limited support of options. Typically, options are translated into variables in native makefiles and can be modified by the user.

This is how setting an option may look with autoconf:

$ ./configure --enable-debug

Or with VC++ makefiles:

C:\> nmake DEBUG=1

Conditions

Condition is a boolean expression that is used to conditionally determine values of variables and also to conditionally disable or enable parts of the makefile. Conditions are commonly used to differ generated native makefiles based on output format and user settings of options.

There are two types of conditions:

Weak

The condition may be any Python expression that only uses variables defined with the set command and Python helper functions from available modules. The expression must evaluate to either 0 (false) or 1 (true).

If it evaluates to 0, then the statement that has the condition associated with it is not processed. If it evalues to 1, that the statement is processed as if it had no condition.

Strong

These conditions depend on the value of an option. Their syntax is very limited compared to weak conditions, because the decisition (condition evaluation) is postponed until make-time -- i.e. generated native makefile contains the condition in some form.

The condition may only take the form of simple test for equality:

OPTION=="VALUE"

Here, OPTION is the name of an already defined option with enumerated possible values and VALUE is one of the option's values.

If a strong conditions is used with the set command, a conditional variable is created.

Examples of valid conditions:

<set var="NUM1">1</set>
<set var="NUM2">10</set>
<set var="RESULT_11" cond="NUM1+NUM2==11">yes</set>
        
<option name="BUILD">
  <values>debug,release</values>
  <default-value>release</default-value>
</option>

<set var="USE_DEBUG" cond="BUILD=='debug'">1</set>
<set var="USE_DEBUG" cond="BUILD=='release'">0</set>

Examples of invalid conditions:

<option name="NUM1">
  <default-value>1</default-value>
</option>
</set>
<set var="NUM2">10</set>
<set var="RESULT_11" cond="NUM1+NUM2==1">yes</set>
        
<option name="BUILD">
  <values>R D</values>
</option>

<set var="USE_DEBUG" cond="BUILD=='debug'">1</set>
     <!-- not in the list of values -->

<option name="BUILD2"></option>

<set var="USE_DEBUG2" cond="BUILD2=='debug'">1</set>
     <!-- not option with enumeration -->

<option name="BUILD3">
  <values>release debug</values>
</option>

<set var="USE_DEBUG3" cond="BUILD!='debug'">1</set>
     <!-- not equality test -->

See also: the section called “Conditional Variables”, set

Conditional Variables

Conditional variables are variables whose value differs depending on a condition. They are created by using the conditional form of set command. Unlike options, they can't be directly modified by user of native makefile. Unlike variables, they are not evaluated by Bakefile during processing (the value depends on values of options).

Summary of differences between options, variables and conditional variables:

TypeValueSet by user
variableconstantno
optionvariableyes
conditional variablevariable (derived from some option)no

Modules

Modules extend Bakefile with additional abilities. For example, standard configuration of Bakefile can't build Python modules. You must explicitly load python module which will add, among other things, python-module rule. Functionality is divided into modules so that generated makefiles are not cluttered with unused options and to avoid unnecessary configure checks.

Presets

Presets are pieces of Bakefile code that can be included in user bakefiles. Their purpose is to provide support for e.g. libraries or tools or to provide commonly used code snippets in convenient form.

For example, Bakefile contains the simple preset that can be used to quickly create makefiles with support for both debug and release builds.

Paths

Regardless of the operating system where Bakefile is running, the convention respected by all Bakefile tags and variables is to use Unix-style paths, i.e. to use forward slash (/) as the path separator.