3.  Variable Expansion

CodeBlocks differentiates between several types of variables. These types serve the purpose of configuring the environment for creating a program, and at the same of improving the maintainability and portability. Access to the CodeBlocks variables is achieved via $<name>.

Envrionment Variable
are set during the startup of CodeBlocks. They can modify system environment variables such as PATH. This can be useful in cases where a defined environment is necessary for the creation of projects. The settings for environment variables in CodeBlocks are made at ’Settings’ /’Environment’ /’Environment Variables’ .
Builtin Variables
are predefined in CodeBlocks, and can be accessed via their names (see Variable Expansion 3.2 for details).
Command Macros
This type of variables is used for controlling the build process. For further information please refer to Variable Expansion 3.4.
Custom Variables
are user-defined variables which can be specified in the build options of a project. Here you can, for example define your derivative as a variable MCU and assign a corresponding value to it. Then set the compiler option -mcpu=$(MCU), and CodeBlocks will automatically replace the content. By this method, the settings for a project can be further parametrised.
Global Variables
are mainly used for creating CodeBlocks from the sources or developments of wxWidgets applications. These variables have a very special meaning. In contrast to all others if you setup such a variables and share your project file with others that have *not* setup this GV CodeBlocks will ask the user to setup the variable. This is a very easy way to ensure the ’other developer’ knows what to setup easily. CodeBlocks will ask for all path’s usually necessary.
 3.1  Syntax
 3.2  List of available built-ins
  3.2.1  Files and directories
  3.2.2  Build targets
  3.2.3  Language and encoding
  3.2.4  Time and date
  3.2.5  Random values
  3.2.6  Operating System Commands
  3.2.7  Conditional Evaluation
 3.3  Script expansion
 3.4  Command Macros
 3.5  Compile single file
 3.6  Link object files to executable
 3.7  Global compiler variables
 3.8  Synopsis
 3.9  Names and Members
 3.10  Constraints
 3.11  Using Global Compiler Variables
 3.12  Variable Sets
  3.12.1  Custom Members Mini-Tutorial

3.1.  Syntax

CodeBlocks treats the following functionally identical character sequences inside pre-build, post-build, or build steps as variables:

Variable names must consist of alphanumeric characters and are not case-sensitive. Variables starting with a single hash sign (#) are interpreted as global user variables (see Variable Expansion 3.7 for details). The names listed below are interpreted as built-in types.

Variables which are neither global user variables nor built-in types, will be replaced with a value provided in the project file, or with an environment variable if the latter should fail.

Note:
Per-target definitions have precedence over per-project definitions.

3.2.  List of available built-ins

The variables listed here are built-in variables of CodeBlocks. They cannot be used within source files.

3.2.1.  Files and directories

$(PROJECT_FILENAME), $(PROJECT_FILE_NAME), $(PROJECT_FILE), $(PROJECTFILE)

The filename of the currently compiled project.

$(PROJECT_NAME)

The name of the currently compiled project.

$(PROJECT_DIR), $(PROJECTDIR), $(PROJECT_DIRECTORY)

The common top-level directory of the currently compiled project.

$(ACTIVE_EDITOR_FILENAME)

The filename of the file opened in the currently active editor.

$(ACTIVE_EDITOR_DIRNAME)

the directory containing the currently active file (relative to the common top level path).

$(ACTIVE_EDITOR_STEM)

The base name (without extension) of the currently active file.

$(ACTIVE_EDITOR_EXT)

The extension of the currently active file.

$(ALL_PROJECT_FILES)

A string containing the names of all files in the current project.

$(MAKEFILE)

The filename of the makefile.

$(CODEBLOCKS), $(APP_PATH), $(APPPATH), $(APP-PATH)

The path to the currently running instance of CodeBlocks.

$(DATAPATH), $(DATA_PATH), $(DATA-PATH)

The ’shared’ directory of the currently running instance of CodeBlocks.

$(PLUGINS)

The plugins directory of the currently running instance of CodeBlocks.

3.2.2.  Build targets

$(FOOBAR_OUTPUT_FILE)

The output file of a specific target.

$(FOOBAR_OUTPUT_DIR)

The output directory of a specific target.

$(FOOBAR_OUTPUT_BASENAME)

The output file’s base name (no path, no extension) of a specific target.

$(TARGET_OUTPUT_DIR)

The output directory of the current target.

$(TARGET_OBJECT_DIR)

The object directory of the current target.

$(TARGET_NAME)

The name of the current target.

$(TARGET_OUTPUT_FILE)

The output file of the current target.

$(TARGET_OUTPUT_BASENAME)

The output file’s base name (no path, no extension) of the current target.

$(TARGET_CC), $(TARGET_CPP), $(TARGET_LD), $(TARGET_LIB)

The build tool executable (compiler, linker, etc) of the current target.

3.2.3.  Language and encoding

$(LANGUAGE)

The system language in plain language.

$(ENCODING)

The character encoding in plain language.

3.2.4.  Time and date

$(TDAY)

Current date in the form YYYYMMDD (for example 20051228)

$(TODAY)

Current date in the form YYYY-MM-DD (for example 2005-12-28)

$(NOW)

Timestamp in the form YYYY-MM-DD-hh.mm (for example 2005-12-28-07.15)

$(NOW_L)

] Timestamp in the form YYYY-MM-DD-hh.mm.ss (for example 2005-12-28-07.15.45)

$(WEEKDAY)

Plain language day of the week (for example ’Wednesday’)

$(TDAY_UTC), $(TODAY_UTC), $(NOW_UTC), $(NOW_L_UTC), $(WEEKDAY_UTC)

These are identical to the preceding types, but are expressed relative to UTC.

3.2.5.  Random values

$(COIN)

This variable tosses a virtual coin (once per invocation) and returns 0 or 1.

$(RANDOM)

A 16-bit positive random number (0-65535)

3.2.6.  Operating System Commands

The variable are substituted through the command of the operating system.

$(CMD_CP)

Copy command for files.

$(CMD_RM)

Remove command for files.

$(CMD_MV)

Move command for files.

$(CMD_MKDIR)

Make directory command.

$(CMD_RMDIR)

Remove directory command.

3.2.7.  Conditional Evaluation

  $if(condition){true clause}{false clause}

Conditional evaluation will resolve to its true clause if

Conditional evaluation will resolve to its false clause if

Note:
Please do note that neither the variable syntax variants %if(...) nor $(if)(...) are supported for this construct.

Example

For example if you are using several platforms and you want to set different parameters depending on the operating system. In the following code the script commands of [[ ]] are evaluated and the <command> will be executed. This could be useful in a post-built step.

  [[ if (PLATFORM ==  PLATFORM_MSW) { print (_T("cmd /c")); } else { print (_T("sh ")); } ]] <command>

3.3.  Script expansion

For maximum flexibility, you can embed scripts using the [[ ]] operator as a special case of variable expansion. Embedded scripts have access to all standard functionalities available to scrips and work pretty much like bash backticks (except for having access to CodeBlocks namespace). As such, scripts are not limited to producing text output, but can also manipulate CodeBlocks state (projects, targets, etc.).

Note:
Manipulating CodeBlocks state should be implemented rather with a pre-build script than with a script.

Example with Backticks

  objdump -D ‘find . -name ⋆.elf‘ > name.dis

The expression in backticks returns a list of all executables *.elf in any subdirectories. The result of this expression can be used directly by objdump. Finally the output is piped to a file named name.dis. Thus, processes can be automatted in a simple way without having to program any loops.

Example using Script

The script text is replaced by any output generated by your script, or discarded in case of a syntax error.

Since conditional evaluation runs prior to expanding scripts, conditional evaluation can be used for preprocessor functionalities. Built-in variables (and user variables) are expanded after scripts, so it is possible to reference variables in the output of a script.

  [[ print(GetProjectManager().GetActiveProject().GetTitle()); ]]

inserts the title of the active project into the command line.

3.4.  Command Macros

$compiler

Access to name of the compiler executable.

$linker

Access to name of the linker executable.

$options

Compiler flags

$link_options

Linker flags

$includes

Compiler include paths

$c

Linker include paths

$libs

Linker libraries

$file

Source file (full name)

$file_dir

Source file directory without file name and file name extension.

$file_name

Source file name without path info and file name extension.

$exe_dir

Directory of executable without file name and file name extension.

$exe_name

File name of executable without path and file name extension.

$exe_ext

File name extension of executable without path and file name.

$object

Object file

$exe_output

Executable output file

$objects_output_dir

Object Output Directory

3.5.  Compile single file

  $compiler $options $includes -c $file -o $object

3.6.  Link object files to executable

  $linker $libdirs -o $exe_output $link_objects $link_resobjects $link_options $libs

3.7.  Global compiler variables

3.8.  Synopsis

Working as a developer on a project which relies on 3rd party libraries involves a lot of unnecessary repetitive tasks, such as setting up build variables according to the local file system layout. In the case of project files, care must be taken to avoid accidentially committing a locally modified copy. If one does not pay attention, this can happen easily for example after changing a build flag to make a release build.

The concept of global compiler variables is a unique new solution for CodeBlocks which addresses this problem. Global compiler variables allow you to set up a project once, with any number of developers using any number of different file system layouts being able to compile and develop this project. No local layout information ever needs to be changed more than once.

3.9.  Names and Members

Global compiler variables in CodeBlocks are discriminated from per-project variables by a leading hash sign. Global compiler variables are structured; every variable consists of a name and an optional member. Names are freely definable, while some of the members are built into the IDE. Although you can choose anything for a variable name in principle, it is advisable to pick a known identifier for common packages. Thus the amount of information that the user needs to provide is minimised. The CodeBlocks team provides a list of recommended variables for known packages.

The member base resolves to the same value as the variable name uses without a member (alias).

The members include and lib are by default aliases for base/include and base/lib, respectively. However, a user can redefine them if another setup is desired.

It is generally recommended to use the syntax $(#variable.include) instead of $(#variable)/include, as it provides additional flexibility and is otherwise exactly identical in functionality (see Variable Expansion 3.12.1 and Global Variable Environment 3.1 for details).

The members cflags and lflags are empty by default and can be used to provide the ability to feed the same consistent set of compiler/linker flags to all builds on one machine. CodeBlocks allows you to define custom variable members in addition to the built-in ones.


pict

Figure 3.1: Global Variable Environment

3.10.  Constraints

CodeBlocks will detect the most obvious cases of recursive definitions (which may happen by accident), but it will not perform an in-depth analysis of every possible abuse. If you enter crap, then crap is what you will get; you are warned now.

Examples

Defining wx.include as $(#wx)/include is redundant, but perfectly legal Defining wx.include as $(#wx.include) is illegal and will be detected by CodeBlocks Defining wx.include as $(#cb.lib) which again is defined as $(#wx.include) will create an infinite loop

3.11.  Using Global Compiler Variables

All you need to do for using global compiler variables is to put them in your project! Yes, it’s that easy.

When the IDE detects the presence of an unknown global variable, it will prompt you to enter its value. The value will be saved in your settings, so you never need to enter the information twice.

If you need to modify or delete a variable at a later time, you can do so from the settings menu.

Example


pict

Figure 3.2: Global Variables

The above image shows both per-project and global variables. WX_SUFFIX is defined in the project, but WX is a global user variable.

3.12.  Variable Sets

Sometimes, you want to use different versions of the same library, or you develop two branches of the same program. Although it is possible to get along with a global compiler variable, this can become tedious. For such a purpose, CodeBlocks supports variable sets. A variable set is an independent collection of variables identified by a name (set names have the same constraints as variable names).

If you wish to switch to a different set of variables, you simply select a different set from the menu. Different sets are not required to have the same variables, and identical variables in different sets are not required to have the same values, or even the same custom members.

Another positive thing about sets is that if you have a dozen variables and you want to have a new set with one of these variables pointing to a different location, you are not required to re-enter all the data again. You can simply create a clone of your current set, which will then duplicate all of your variables.

Deleting a set also deletes all variables in that set (but not in another set). The default set is always present and cannot be deleted.

3.12.1.  Custom Members Mini-Tutorial

As stated above, writing $(#var.include) and $(#var)/include is exactly the same thing by default. So why would you want to write something as unintuitive as $(#var.include)?

Let’s take a standard Boost installation under Windows for an example. Generally, you would expect a fictional package ACME to have its include files under ACME/include and its libraries under ACME/lib. Optionally, it might place its headers into yet another subfolder called acme. So after adding the correct paths to the compiler and linker options, you would expect to #include <acme/acme.h> and link to libacme.a (or whatever it happens to be).